Bash
(bash) 腳本 A,等待腳本 B,但不是它的子程序
所以我有 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