當其中一個子行程失敗時,我試圖讓 GNU 并行中止所有處理。該選項--halt now,fail=1正確執行此操作:如果子行程以非零退出代碼退出,或者如果它被 sigkilled(由 OOM 殺手),parallel將停止所有作業。
如果parallel檢測到非零退出代碼,它本身將使用相同的非零退出代碼退出。這讓父腳本可以檢測到出現問題。
問題是在子行程被 sigkilled 的情況下,并行本身的回傳代碼為零,并且父腳本無法判斷行程失敗。
這是該問題的演示(單個作業以使其保持簡單,但對于花費不同時間的多個作業等存在相同的問題)。
# Create script that will SIGKILL itself.
cat << 'EOF' > selfkill.sh
echo Process $BASHPID will now terminate itself
kill -9 $BASHPID
EOF
# And another that will exit with code 1.
cat << 'EOF' > exit_one.sh
echo Process $BASHPID will now exit with code 1
exit 1
EOF
echo Running exit_one.sh via parallel with default error handling
parallel --joblog job.log bash exit_one.sh ::: 1
echo Exit code is $?
cat job.log
echo
echo Running selfkill.sh via parallel with default error handling
parallel --joblog job.log bash selfkill.sh ::: 1
echo Exit code is $?
cat job.log
echo
echo Running exit_one.sh via parallel with abort on error
parallel --joblog job.log --halt now,fail=1 bash exit_one.sh ::: 1
echo Exit code is $?
cat job.log
echo
echo Running selfkill.sh via parallel with abort on error
parallel --joblog job.log --halt now,fail=1 bash selfkill.sh ::: 1
echo Exit code is $?
cat job.log
輸出:
Running exit_one.sh via parallel with default error handling
Process 1521789 will now exit with code 1
Exit code is 1
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665764801.403 0.002 0 42 1 0 bash exit_one.sh 1
Running selfkill.sh via parallel with default error handling
Process 1521804 will now terminate itself
Exit code is 1
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665764801.573 0.003 0 42 0 9 bash selfkill.sh 1
Running exit_one.sh via parallel with abort on error
Process 1521819 will now exit with code 1
parallel: This job failed:
bash exit_one.sh 1
Exit code is 1
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665764801.730 0.003 0 42 1 0 bash exit_one.sh 1
Running selfkill.sh via parallel with abort on error
Process 1521834 will now terminate itself
parallel: This job failed:
bash selfkill.sh 1
Exit code is 0
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665764801.880 0.001 0 42 0 9 bash selfkill.sh 1
一切都很好,除了最后一種情況,因為出現問題,我需要一個非零退出代碼。
測驗作業在被 sigkilled 時似乎以代碼 137 退出,所以我希望它會被檢測到。然而parallel,不知何故能夠看到它被殺死(好)但然后以零退出(不好)。也許該--halt選項導致parallel認為自己成功,因為它成功地停止了所有其他行程?這種行為有解決方法嗎?
$ bash selfkill.sh
Process 1485899 will now terminate itself
Killed
$ echo $?
137
這是在帶有 GNU 并行 20161222 和 bash 5.0.17 的 Ubuntu 20.04 上。
如果這是一個 XY 問題,并且有比使用 GNU 并行更好的方法,請提供進一步的背景關系。最初我們沒有使用 GNU 并行。通過大量使用&. 但是我們無法找到一種方法來檢測作業何時被 sigkilled 并且父腳本將繼續執行與上面示例中的操作大致相同的操作。
uj5u.com熱心網友回復:
<sigh> 在問這里之前我應該??嘗試一個更新的版本。
Ubuntu 20.04 卡在舊版本上,但我能夠在 Docker 容器中進行試驗docker run --rm -it ubuntu:22.04,我可以在其中安裝 GNU 并行 20210822。
Running exit_one.sh via parallel with default error handling
Process 1179 will now exit with code 1
Exit code is 1
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665765327.768 0.100 0 39 1 0 bash exit_one.sh 1
Running selfkill.sh via parallel with default error handling
Process 1186 will now terminate itself
Exit code is 1
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665765328.292 0.092 0 39 0 9 bash selfkill.sh 1
Running exit_one.sh via parallel with abort on error
Process 1193 will now exit with code 1
parallel: This job failed:
bash exit_one.sh 1
Exit code is 1
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665765328.818 0.111 0 39 1 0 bash exit_one.sh 1
Running selfkill.sh via parallel with abort on error
Process 1200 will now terminate itself
parallel: This job failed:
bash selfkill.sh 1
Exit code is 137
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1665765329.321 0.085 0 39 0 9 bash selfkill.sh 1
之前有問題的最后一個案例現在以 137 退出,這很好并且與 bash 看到的一致。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/515832.html
上一篇:如何正確使用內部欄位分隔符?
