script1
私たちは以下からスクリプトを実行します。script_main
script_main
:
#!/bin/bash
/tmp/script1
echo $?
sleep 2
echo script ended
script1
:
#!/bin/bash
exit 1
明らかにscript1
終了コードは1ですが、デフォルトのスクリプトは最後まで実行され続けます。
私の質問:いつscript1
すぐにexit 1
停止できますかmain_script
?
答え1
最も簡単な方法は、exit
他のスクリプトが失敗したときに最初のスクリプトを明示的に使用することです。条件にスクリプト実行を入れます。
otherscript.sh || exit 1
または
if ! otherscript.sh ; then
ret=$?
echo "otherscript failed with exit code $ret. exit." >&2
exit 1
fi
これにより、基本スクリプトが必要なクリーンアップを実行したり、子プロセスの終了コードに基づいて別の解決策を試したりできます。最初に、|| exit
just 、 を使用して子プロセスの終了コードを渡すことができます。
基本スクリプトを終了するにはどのコマンドは開始されませんset -e
。
set -e
otherscript.sh
echo "this will not run if otherscript fails"
set -e
条件付き構造内で実行されているプログラムでは機能しないため、特定のコードをテストしたりエラーを無視したりすることができます|| true
。ただし、シャットダウンポイントがどこにでもあるため、trap somecmd EXIT
シェルがシャットダウンする前にどこに発生してもクリーンアップを実行できます。
内部スクリプトを使用して基本スクリプトを強制的に終了することも可能ですが、これはやや非友好的であり、一般的なアプリケーションではこれを行うことを期待していません。ただし、必要に応じて、内部スクリプトに単に親プロセスを撮影させることもあります。
$ cat mainscript.sh
#!/bin/bash
./otherscript.sh
echo "$0 exiting normally"
$ cat otherscript.sh
#!/bin/bash
echo "$0 kill $PPID"
kill $PPID
$ bash mainscript.sh
./otherscript.sh kill 11825
Terminated
ここで対話型シェルで実行すると、otherscript.sh
対話型セッションをキャプチャしようとします。SIGTERM
しかし、私がテストしたすべてのシェルは、対話的に実行されたときにそれを無視するようです。それにもかかわらず、メインシェルは再trap
利用できますSIGTERM
。
kill 0
単に親プロセスをキャッチする代わりに、実行中のプロセスグループ内のすべてのプロセスを終了する方法を使用できますotherscript.sh
。非対話型シェルで実行される場合、通常は親プロセスが含まれます。
答え2
ソースを使用できますscript 2
。良い:
. /tmp/script1.sh
終了コードを読み、script2
プロセスを終了します。
➜ /tmp cat script.sh
#!/bin/bash
echo "Running ${0} with pid $$"
. /tmp/script1.sh
echo $?
echo "This code won't execute"
sleep 2
echo "Script ${0} ended"
echo "This code won't execute"
sleep 2
echo "Script ${0} ended"
➜ /tmp cat script1.sh
#!/bin/bash
echo "Running ${0} with pid $$"
exit 5
実行してください:
➜ /tmp ./script.sh
Running ./script.sh with pid 10306
Running ./script.sh with pid 10306
➜ /tmp echo $?
5