set -e
サブシェルへの影響はトップシェルと同じだと思います。明らかにこれは本当ではありません。これ:
(
set -e
false
true
) || echo false1
bash -ec '
set -e
false
true
' || echo false2
bash <<EOF || echo false3
set -e
false
true
EOF
bash <<EOF || echo false4
false
true
EOF
bash <<EOF || echo false5
false &&
true
EOF
印刷
false2
false3
false5
これはどこで録音されましたか?すべてのコマンドを接続せずに&&
(または各コマンドの後に何もしないで|| exit $?
)、エラーが発生してサブシェルを終了できますか?
編集する:
私の具体的なユースケースは次のとおりです。
set -e
# ...
status=0
( false; true ) || status=$?
report_code $status
return $status
サブシェルの内容は実際のコードです。この問題は、常にステータスを0に設定し、外部設定のために-eを置き換えると||
不要なエラー終了が発生することです。;
私は以下を使用して問題を解決しました。
set -e
# ...
set +e
( false; true ); status=$?
set -e
report_code $status
return $status
これを行う必要がないことを願っていますが、すべての一般的なシェルはexeced-subshelとjust-forked-subshelの二分法を示すようです。
#!/bin/sh
echo FORK\'D:
export SH
for SH in dash bash ksh zsh; do
$SH -c 'st=0; ( set -e; false; true ) || st=$?; printf "%s\t%s\n" $SH $st; '
done
echo EXEC\'D:
for SH in dash bash ksh zsh; do
$SH -c 'st=0; '$SH' -c " set -e; false; true " || st=$?; printf "%s\t%s\n" $SH $st; '
done
出力:
FORK'D:
dash 0
bash 0
ksh 0
zsh 0
EXEC'D:
dash 1
bash 1
ksh 1
zsh 1
答え1
観察する:
$ ( set -e; false ; true ) || echo false1
$ ( set -e; false ; true ) ; echo code=$?
code=1
返品:
$ ( set -e; false ; true; echo inside=$? ) || echo false1
inside=0
明らかにサブシェルの後ろにある場合、コマンドに到達||
するとサブシェルset -e
は終了しません。false
代わりに、サブシェルは引き続き実行されますtrue
(and echo inside=$?
)。
set -e
通常、見つからないエラーに対してのみ存在するというアイデアです。ここで、外部サブシェルの存在は、サブシェル||
内部のエラーが「捕捉されている」ので、set -e
post-exitが発生しないことをシェルに知らせるようですfalse
。
set -e
驚くべき行動がたくさんあります。バラより「なぜset -eが私が期待するように動作しないのですか?」
文書
上記の動作は次の文書で示されていますman bash
。
-e
パイプ(単一の単純コマンドで構成することができます)、リスト、または複合コマンド(上記のSHELL GRAMMARを参照)がゼロ以外の状態で終了したらすぐに終了します。 失敗したコマンドがシェルの場合、シェルは終了しません。コマンドリスト部分はwhileキーワードまたはUntilキーワードの直後に続き、テスト部分はifまたはelif予約語の後に続きます。&&または||内で実行されるコマンドの一部のリスト最後の&&または||後の最後のコマンドまたは!に反転したコマンドの戻り値を除く、パイプライン内のすべてのコマンド。 -e が省略されたときにコマンドが失敗したため、サブシェルの外部の複合コマンドがゼロ以外の状態を返した場合、シェルは終了しません。 ERR トラップが設定されると、シェルが終了する前に実行されます。このオプションは、シェル環境と各サブシェル環境(上記のコマンドの実行環境を参照)に個別に適用され、サブシェルのすべてのコマンドを実行する前にサブシェルを終了できます。 [強調する。 ]