プロセス置換を使用するときに終了コードを正しくキャプチャしてエラーを処理する方法は?

プロセス置換を使用するときに終了コードを正しくキャプチャしてエラーを処理する方法は?

以下を使用してファイル名を配列に解析するスクリプトがあります。SOのQ&A:

unset ARGS
ARGID="1"
while IFS= read -r -d $'\0' FILE; do
    ARGS[ARGID++]="$FILE"
done < <(find "$@" -type f -name '*.txt' -print0)

これは非常に効率的で、あらゆる種類のファイル名のバリエーションを完全に処理します。しかし、時には存在しないスクリプトにファイルを渡します。たとえば、次のようになります。

$ findscript.sh existingfolder nonexistingfolder
find: `nonexistingfile': No such file or directory
...

一般的な状況では、スクリプトは同様の終了コードをキャプチャし、RET=$?それを使用して進行方法を決定します。上記のプロセス置換では機能しないようです。

この状況で正しい手順は何ですか?戻りコードをキャプチャする方法は?交換プロセス中に問題が発生したかどうかを確認するためのより適切な方法はありますか?

ベストアンサー1

標準出力に戻り値を反映することで、サブシェルプロセスの戻り値を簡単に取得できます。プロセスの交換も同様です。

while IFS= read -r -d $'\0' FILE || 
    ! return=$FILE
do    ARGS[ARGID++]="$FILE"
done < <(find . -type f -print0; printf "$?")

私が実行すると、最後の行は -(または\0適切に区切られた部分)返品の状態はですfindreadEOFを受け取ると1を返します。したがって、$return設定される唯一の時間は、$FILE情報の最後のビットを読み取るときです。

私は余分な行をprintf追加するのを避けました。これは、NULで区切られていない通常の実行でも、先ほど読み取ったデータが1行で終わらないとゼロ以外の値を返すため、\n重要です。したがって、最後の行がewlineで終わらない場合は、変数で読み取られた最後の値が戻り値になります。read\0\n\n

上記のコマンドを実行した後、次の手順を実行します。

echo "$return"

出力

0

公正交換部品​​を変えると..

...
done < <(! find . -type f -print0; printf "$?")
echo "$return"

出力

1

より簡単なデモ:

printf \\n%s list of lines printed to pipe |
while read v || ! echo "$v"
do :; done

出力

pipe

実際に返す内容がプロセスの置き換え(またはそのように読み込まれたサブシェルプロセス)でstdoutに最後に書き込まれたものである限り、そのようなことが$FILE発生した場合は常に希望の戻り状態が渡されます。 。したがって、この|| ! return=...セクションは必ずしも必要ではありません。概念を説明するためにのみ使用されます。

おすすめ記事