別のスクリプトのスクリプトを呼び出しますが、子がexitを呼び出した場合は親を終了しません


11

first.sh

#! /bin/ksh
echo "prova"
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
echo "ho lanciato il terzo"

second.sh

echo "sono nel secondo script"
dosomething1
exit $?

場合はsecond.sh検出状況とエラーして終了-9、first.sh常に終了します。子シェルが終了した場合、最初のシェルを終了しないようにするにはどうすればよいですか?

編集できませんsecond.sh


ここ.では、現在のシェルの別のファイルを読み込むコマンドを使用しています。関連する子シェルまたはサブシェルはありません。あなたがするもしかして実行 second.shし、third.shそれらを調達するのではなく?
Celada、2015

はい。私は代わりに実行を書く必要があります。./?「exit $?」を無視したい second.sh ..の内部はsecond.shを編集しなくても可能ですか?
user3589887 2015

回答:


13

あなたがここでやっていることを含めているsecond.shthird.shシェルプログラミングで「調達」と呼ばれ、同じプロセス内で実行中のサブスクリプト、など。. ./second.sh基本的にsecond.sh、その時点でのテキストを含めることと同じです。exitコマンドは、プロセスを終了し、それは問題では、元のスクリプトまたはソース化スクリプトでそれを呼び出すかどうません。

あなたがしたいすべてがでコマンドを実行している場合second.shthird.sh、彼らは子プロセスとして、これらのスクリプトを呼び出して、アクセスする必要があるか、元のスクリプトから変数や関数を変更しないでください。

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

元のスクリプトから変数や関数にアクセスするために他のスクリプトが必要だが、それらを変更しない場合は、これらのスクリプトをサブシェルで呼び出します。サブシェルは個別のプロセスであるため、サブシェルexitだけが終了します。

#! /bin/ksh
echo "prova"
(. ./second.sh)
echo "ho lanciato il secondo"
(. ./third.sh)
echo "ho lanciato il terzo"

あなたがで定義された変数や関数を使用する必要がある場合second.shthird.sh、親スクリプトでは、あなたはそれらを調達維持する必要があります。

return組み込みは、プロセス全体ではなく、ソーススクリプトのみを終了します。これは、.コマンドに別のスクリプトを含めることと、親スクリプトにそのテキストを含めることの数少ない違いの1つです。ソース化スクリプトのみを呼び出す場合はexitトップレベルで内部の機能とは反対に、あなたは変更することができますexitreturn。エイリアスを使用して、スクリプトを変更せずにそれを行うことができます。

#! /bin/ksh
echo "prova"
alias exit=return
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
unalias exit
echo "ho lanciato il terzo"

exit関数内でも呼び出される場合、私は面倒でない方法はないと思います。面倒な方法は、終了トラップを設定してコードをそこに配置することです。

#!/bin/ksh
do_first () {
  echo "prova"
  trap "after_second" EXIT
  . ./second.sh
  after_second
}
after_second () {
  echo "ho lanciato il secondo"
  trap "after_third" EXIT
  . ./third.sh
  after_third
}
after_third () {
  trap - EXIT
  echo "ho lanciato il terzo"
}
do_first

このため、「。」の使用をやめました。ファイルをスクリプトにソースし、代わりに排他的に「ソース」を使用するようにします。IMOは、bashの「ベストプラクティス」と見なす必要があります。これにより、コードの実行内容がより明確になります。
マークE.ハミルトン

6

2番目と3番目のシェルを取得する代わりに、他のコマンドと同じように実行します。次のように、必要に応じて終了コードを保存して使用できます。

#! /bin/ksh
echo "prova"

# execute and capture stdout ... output of second is not seen ...
OUTPUT1=$(./second.sh)

# find out exit status of second.sh
STATUS1=$?

# ... until now
echo $OUTPUT1

# do something based on the result
if [ $STATUS1 -eq 0 ]; then 
  echo "second.sh ran successfully"
else 
  echo "second.sh crapped out"
fi

# and so on...

STATUS1=$?以前に発行されたechoコマンドの結果をキャッチし./second.shます。これはの結果とは無関係です。
Cromax 2017年

@Cromaxあなたは完全に正しいです。回答が編集されました。
デールアンダーソン

0

この方法で試してください(最初.にを呼び出してから削除してくださいsecond.sh)。

first.sh

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

second.sh

echo "sono nel secondo script"
dosomething1
exit $?

これは、2番目のスクリプトが最初のスクリプトの一部として含まれる原因となる.ショートコードでsourceあるためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.