bash + 補助スクリプトとメインスクリプトを同時に終了する方法

bash + 補助スクリプトとメインスクリプトを同時に終了する方法

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

これにより、基本スクリプトが必要なクリーンアップを実行したり、子プロセスの終了コードに基づいて別の解決策を試したりできます。最初に、|| exitjust 、 を使用して子プロセスの終了コードを渡すことができます。

基本スクリプトを終了するにはどのコマンドは開始されません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

関連情報