スクリプトを実行します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
すぐに停止しますか?
最も簡単な方法は、他のスクリプトが失敗した場合に最初のスクリプトを明示的にexit
にすることです。次のようにスクリプトを条件付きで実行します
otherscript.sh || exit 1
または
if ! otherscript.sh ; then
ret=$?
echo "otherscript failed with exit code $ret. exit." >&2
exit 1
fi
これにより、メインスクリプトが必要なクリーンアップを実行したり、おそらく子の終了コードに応じて他の解決策を試したりできるようになります。最初のコードでは、|| exit
だけを使用して、子の終了コードを渡すことができます。
anyコマンドが開始したときにメインスクリプトを終了させたい場合は、set -e
を使用します。
set -e
otherscript.sh
echo "this will not run if otherscript fails"
set -e
は、条件付き構文内で実行されるプログラムには適用されないため、特定のコードをテストしたり、|| true
を使用してコードをテールしたりして、失敗を無視できます。しかし、今やどこにでも出口点があるので、trap somecmd EXIT
を使用して、シェルが終了する前に、それがどこで発生するかに関係なく、クリーンアップを実行できます。
内部スクリプトがメインスクリプトを強制的に終了させることも可能ですが、やや不親切で、通常のアプリケーションがそれを実行するとは思わないでしょう。ただし、必要に応じて、内部スクリプトを単純に古いプロセスの親プロセスで実行させるのも1つの方法です。
$ 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
が実行されているすべてのプロセスを強制終了できます。非対話型シェルから開始した場合、通常は親が含まれます。
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