サブシェル/サブプロセスのbash 'nounset'はデフォルトスクリプトを強制終了しません。この問題をグローバルにどのように解決できますか?

サブシェル/サブプロセスのbash 'nounset'はデフォルトスクリプトを強制終了しません。この問題をグローバルにどのように解決できますか?

次のスクリプトを使用してください。tstNounset.sh

#!/bin/bash
set -x 
set -o nounset;set -u

echo `echo $str`
function FUNC1() { echo $str; };export -f FUNC1;bash -c FUNC1
function FUNC2() { set -u;echo $str; };export -f FUNC2;bash -c FUNC2
echo "A - should not reach here?"
echo $str
echo "B - doesn't reach here."

すべての変数をチェックせずにグローバルに「A」に到達するのを防ぎたいです。

どちらも使用されませんset -e。ほとんどのエラーと回避策は単なる警告であるため、ほとんどのエラーと解決策に対処したためです。

検出する方法があるかどうか疑問に思います。「バインドされていない変数」サブシェル/サブプロセスでも発生するので、強制的に終了できますか?

仕事ができない_each_コマンドを使用して、エラーに対して特定のタスクを実行するようにbashスクリプトにどのように指示できますか?またはTrapコマンドを使用してエラーをトリガーする方法返品。私はこれを見つけました古い質問また。

答え1

サブシェル

サブシェルはスクリプト全体を終了できません。の影響で、set -uサブシェルは自分の両親に「ねえ、これを致命的なエラーとして扱いたい」と言うことはできません。set -u子シェルでは機能しますが、親シェルでは機能しない場合でも意味はありません。サブシェルができることは、ゼロ以外の終了コードを返すことです。手動でまたはを介して親エントリの終了コードを処理できますset -e

(set -u; …; echo $undefined_variable)
# here $? is nonzero
ret=$?; if [ $ret -ne 0 ]; then exit $ret; fi

サブプロセス

ここでやっていることはサブシェルではありません。別のプログラムを起動することです。他のプログラムは現在のスクリプトを実行しているインタプリタでもあるbashですが、これは偶然の一致です。 bashが呼び出すプログラムの設定によってbash自体が終了する理由はまったくありません。

set +e
bash -c 'do something'
echo "A - should and does reach here"

これはあなたが書いたものと変わりませんperl -e 'use strict; print $barf'。 Perlは終了し、ゼロ以外の状態を返しますが、これはbashスクリプトを終了しません(以下を除くset -e)。set -e子プロセスがゼロ以外の戻りコードを返すときに終了するために使用します。

答え2

私のスクリプトは誤ってコーディングされていますが、修正できます。

最初、2番目、3番目のコメントを見てください。

  • 最初はエラーをキャッチする必要があります。
  • 第二の間違い、閉じ込められないように注意してください!それを使用しないと、if ! ...$?を使用して戻り値を取得できませんか?
  • 第三に、直接エコーするのではなく、中間変数を使用してエラーをキャッチできます。

tstNounset.sh:

#!/bin/bash
trap 'ErrorHappened;exit 1' ERR #1st A TRAP ERR IS REQUIRED

set -x 
set -o nounset;set -u

#echo `echo $str`
nRet=0;if strA="`echo $str`";then : ;else nRet=$?;echo "Err$nRet";fi #2rd errors that you take care wont be trapped! do not use `if ! ...` will prevent getting return value with $?
echo "0 - should not reach here?"
strA="`echo $str`";echo "$strA" #3nd DO NOT ECHO DIRECTLY, use a intermediary variable so the error can be cautch
echo "1 - should not reach here?"
function FUNC1() { echo $str; };export -f FUNC1;bash -c FUNC1
function FUNC2() { set -u;echo $str; };export -f FUNC2;bash -c FUNC2
echo "A - should not reach here?"
echo $str
echo "B - doesnt reach here."

関連情報