鉴于管道
a | b | c
如果生成错误或匹配输入流中的特定模式,我该如何更改才能b
中止管道?b
答案1
@mosvy非常有帮助回答曾是大多正确,但存在无论是否遇到“die”b()
总是中止管道的问题: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的版本中,b()
总是中止管道,因为sed /die/q
如果遇到“die”,则返回退出代码0(成功)或者到达输入流的末尾,因此b()
始终调用kill "$BASHPID"
.
在下面的版本中,我更正了@mosvy的答案,以便b()
中止管道仅有的当它在输入流中遇到“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
请注意,在此版本的 中b()
,如果sed
遇到“die”,它会调用q 2
导致立即终止并退出代码 2(失败)的命令sed
,然后||
调用kill "$BASHPID"
该命令终止b()
管道中的进程并中止管道。 (注意这个版本需要GNUsed
哪个扩展命令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