最近、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