Bash

(bash) 腳本 A,等待腳本 B,但不是它的子程序

  • July 27, 2017

所以我有 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 的所有實例在繼續之前完成,這是目前所做的,但它也在等待不那麼重要的東西的後台 rsyncs。這些是我不想等待的較大文件。

我已經閱讀了nohup、disown 和 & 之間的區別,並嘗試了不同的組合,但我沒有得到我想要的結果。

在這一點上,我很困惑。任何幫助,將不勝感激!

這裡的問題是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

引用自:https://unix.stackexchange.com/questions/382156