これはbashのバグですか?パイプから呼び出すと、 'return' は関数を終了しません。

これはbashのバグですか?パイプから呼び出すと、 'return' は関数を終了しません。

最近、bashを使っていくつかの奇妙な問題に直面しました。スクリプトを簡素化しようとしている間、私は次のような小さなコードを考えました。

$ o(){ echo | while read -r; do return 0; done; echo $?;}; o
0
$ o(){ echo | while read -r; do return 1; done; echo $?;}; o
1

return関数は印刷せずに終了する必要があります$?。そうではありませんか?さて、それからパイプから一人で戻ることができることを確認しました。

$ echo | while read -r; do return 1; done
bash: return: can only `return' from a function or sourced script

ループなしで同じことが起こりますwhile

$ foo(){ : | return 1; echo "This should not be printed.";}
$ foo
This should not be printed.

ここで何か抜けましたか? Google 検索結果がありません。私のバッシュバージョンは4.2.37(1)-リリースDebian Wheezy から。

ベストアンサー1

これはバグではありませんがbash記録された行動:

パイプラインの各コマンドは、独自のサブシェルで実行されます。

このreturnコマンドは関数定義内で有効ですが、サブシェルでも親シェルに影響を与えないため、echo次のコマンドは関係なく実行されます。しかし移動が不可能な住宅建築だからPOSIX規格パイプラインで構成されたコマンドは、サブシェル(デフォルト)または最上位レベル(許可された拡張)で実行できます。

さらに、マルチコマンドパイプラインの各コマンドはサブシェル環境にありますが、拡張機能によってパイプラインの一部またはすべてのコマンドを現在の環境で実行できます。他のすべてのコマンドは、現在のシェル環境内で実行する必要があります。

bash次のいくつかのオプションが期待どおりに機能できることを願っています。

$ set +m # disable job control
$ shopt -s lastpipe # do not run the last command of a pipeline a subshell 
$ o(){ echo | while read -r; do return 0; done; echo $?;}
$ o
$          <- nothing is printed here

おすすめ記事