サブシェルで-eを設定する

サブシェルで-eを設定する

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 -epost-exitが発生しないことをシェルに知らせるようですfalse

set -e驚くべき行動がたくさんあります。バラより「なぜset -eが私が期待するように動作しないのですか?」

文書

上記の動作は次の文書で示されていますman bash

-e

パイプ(単一の単純コマンドで構成することができます)、リスト、または複合コマンド(上記のSHELL GRAMMARを参照)がゼロ以外の状態で終了したらすぐに終了します。 失敗したコマンドがシェルの場合、シェルは終了しません。コマンドリスト部分はwhileキーワードまたはUntilキーワードの直後に続き、テスト部分はifまたはelif予約語の後に続きます。&&または||内で実行されるコマンドの一部のリスト最後の&&または||後の最後のコマンドまたは!に反転したコマンドの戻り値を除く、パイプライン内のすべてのコマンド。 -e が省略されたときにコマンドが失敗したため、サブシェルの外部の複合コマンドがゼロ以外の状態を返した場合、シェルは終了しません。 ERR トラップが設定されると、シェルが終了する前に実行されます。このオプションは、シェル環境と各サブシェル環境(上記のコマンドの実行環境を参照)に個別に適用され、サブシェルのすべてのコマンドを実行する前にサブシェルを終了できます。 [強調する。 ]

おすすめ記事