パイプラインのコマンドはどのようにパイプラインを中断できますか?

パイプラインのコマンドはどのようにパイプラインを中断できますか?

パイプラインを考えると

a | b | c

bエラーが発生した場合、または入力ストリームの特定のパターンと一致した場合、パイプラインを中断するには何を変更する必要がありますか?b

ベストアンサー1

@モスビーとても役に立つ回答以前は最大そうですね。ただし、b()「die」が発生しているかどうかにかかわらず、常にパイプラインを停止する問題があります。sed /die/q

入力ストリームに「die」が含まれています。

$ b(){ sed /die/q && kill "$BASHPID"; }; printf '%s\n' pass die oops | b | cat; echo "${PIPESTATUS[@]}"
pass
die
0 143 0

入力ストリーム確かに「死」という言葉が含まれています。

$ b(){ sed /die/q && kill "$BASHPID"; }; printf '%s\n' pass oops | b | cat; echo "${PIPESTATUS[@]}"
pass
oops
0 143 0

@mosvy バージョンでは "die" が発生すると終了コード 0 が返されるので (成功)b()パイプラインは常に中断されます。sed /die/qまたは入力ストリームの終わりに達したので、b()常に呼び出されますkill "$BASHPID"

以下のバージョンでは、b()パイプが中断されるように@mosvyの回答を修正しました。ただ入力ストリームで「die」を見つけた場合:

入力ストリームに「die」が含まれています。

b() {
  sed '/die/{q 2}' || kill "$BASHPID"
}

# Send "die" to b.
printf '%s\n' pass die oops | b | cat

echo "${PIPESTATUS[@]}"

出力:

pass
die
0 2 0

入力ストリーム確かに「死」という言葉が含まれています。

b() {
  sed '/die/{q 2}' || kill "$BASHPID"
}

# Do not send "die" to b.
printf '%s\n' pass oops | b | cat

echo "${PIPESTATUS[@]}"

出力:

pass
oops
0 0 0

このバージョンでは、「die」が見つかっb()たら、終了コード2(失敗)ですぐに終了するコマンドをsed呼び出します。その後、このコマンドが呼び出され、パイプのプロセスを終了してパイプを中断します。 (このバージョンではq 2sed||kill "$BASHPID"b()牛に似た一種の栄養sedどの拡張コマンドq終了コードを受け入れます。 )

@mosvyが述べたように、「意識的な自殺」を犯すのではなく、次のプロセスから始めてくださいb()exit

b() {
  sed '/die/{q 2}' || exit 3
}

# Send "die" to b.
printf '%s\n' pass die oops | b | cat

echo "${PIPESTATUS[@]}"

出力:

pass
die
0 3 0

おすすめ記事