(bash)脚本A,等待脚本B,但不等待其子进程


9

所以我有scriptA可以做到:

ssh server1 -- scriptB &
ssh server2 -- scriptB &
ssh server3 -- scriptB &
wait
otherstuffhappens

ScriptB可以:

rsync -av /important/stuff/. remoteserver:/remote/dir/.
rsync -av /not/so/important/stuff/. remoteserver:/remote/dir/. &
exit

我期望的结果是scriptA在继续进行之前将等待scriptB的所有实例完成,这是它当前正在执行的操作,但是它也在等待不太重要的东西的后台rsync。这些是我不想等待的较大文件。

我已经阅读了nohup,disown和&之间的区别,并尝试了不同的组合,但是我没有得到想要的结果。

在这一点上,我很沮丧。任何帮助,将不胜感激!

Answers:


15

这里的问题是,它正在sshd等待从中读取命令的标准输出(出于某种原因而不是标准错误,至少是我正在测试的版本)的管道上的文件结束。后台作业将fd继承到该管道。

因此,要解决此问题,请将该后台rsync命令的输出重定向到某个文件,或者/dev/null如果您不关心它,则将其重定向。您还应该重定向stderr,因为即使sshd不在等待相应的管道,sshd退出后管道也将断开,因此rsync如果尝试在stderr上进行写操作将被杀死。

所以:

rsync ... > /dev/null 2>&1 &

相比:

$ time ssh localhost 'sleep 2 &'
ssh localhost 'sleep 2 &'  0.05s user 0.00s system 2% cpu 2.365 total
$ time ssh localhost 'sleep 2 > /dev/null &'
ssh localhost 'sleep 2 > /dev/null &'  0.04s user 0.00s system 12% cpu 0.349 total

和:

$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null &'; sleep 2; cat out
141  # ls by killed with SIGPIPE upon writing the error message
$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null 2>&1 &'; sleep 2; cat out
2    # ls exited normally after writing the error on /dev/null instead
     # of a broken pipe


3

-f用于ssh解决问题的标志。经过测试:

#!/bin/sh -e
echo $$_script__begin
( echo sleeping; sleep 2; echo slept )&
echo $$_script__end

当我使用运行它时ssh localhost ./script,它一直等到slept显示出来。带有该-f标志的标志在退出,echo $$_script__end然后sleptssh命令返回后在后台显示。


2

这是OpenSSH服务器的已知问题,在上游Bugzilla#2071中对此进行了描述和讨论。在该错误中,在OpenSSH方面以及该脚本中都提出了几种解决方法。

如果你想等待脚本的输出,你应该增加一个wait之前exitscriptB了。

如果您不关心输出,请使用nohup和IO重定向到的一些变体/dev/null,这将以相同的方式解决问题。


1

你可以试试看 $!是默认的Shell变量,其中包含最近执行的后台管道/进程的进程ID。

command1 &
lpid1=$!

command2 &
lpid2=$!

command3 &
lpid=$!

wait $lpid1  # waits for only the process with PID lpid1  to complete. 

您需要通过使用export变量等根据脚本来利用它


1

B只需要等待它自己的后台进程:

rsync -av /important/stuff/. remoteserver:/remote/dir/.
rsync -av /not/so/important/stuff/. remoteserver:/remote/dir/. &
wait
exit

到那时,您最好不要在后台运行第二个rsync并避免wait完全使用它。尽管我猜测OP的意思是rsync并行运行两个进程,这意味着(使用)同时使用将它们同时后台。无论如何,我都同意这是解决问题的最直接方法,也是我根据问题信息选择的一种方法。&wait
David Z
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.