从进程替换扫描
如果您创建一个 shell 函数 testcmd 来检查您的字符串并在看到它时采取行动(请注意,此行动可能类似于运行程序或创建文件;您设置的任何变量都不会对启动管道的父 shell 可见),这看起来像:
findit() {
awk '
BEGIN { rc=1 } # starting: unless we find the pattern, exit w/ an error
$0 ~ /foo bar$/ && rc == 1 { rc=0; next } # found the first line
$0 == "" && rc == 0 { exit } # success; found our pattern
{ rc=1 } # reset: saw a line that did not trigger a next or exit above
END { exit(rc) } # honor rc as exit status
'
}
testcmd() { findit && { echo "Found the pattern" >&2; touch found; }; }
Command1 | tee >(testcmd) | Command2 | Command3
此代码将在Command1 的输出中看到foo bar\n\n(假设\ns 旨在表示文字换行符)时创建found 文件,而无需等待Command2 或@987654329 @(或者甚至等待 Command1 完成,如果在发出此字符串后它还有更多输出)。
>(...) 语法是process substitution,它提供了一个文件名,可用于写入... 中复合命令的标准输入。
这不会中断Command2 和Command3 的操作,因为tee 会忽略一个提前停止读取的输出,并继续将内容传递给它的其他输出,只要有更多输入可用并且至少一个输出正在接受写。
测试上述内容
为了测试上述逻辑,我们可以定义如下函数:
Command1() {
printf '%s\n' 'first line' 'prefix foo bar' '' 'last line'
}
Command2() {
echo "command2 reading" >&2
in=$(cat)
sleep 1
echo "command2 writing" >&2
printf '%s\n' "$in"
}
Command3() { echo "command3 read $(wc -l) lines"; }
...Command1 | tee >(testcmd) | Command2 | Command3 的组合输出是:
command2 reading
Found the pattern
command2 writing
command3 read 4 lines
(您可能在command2 reading 之前有Found the pattern - 它们之间的顺序是未定义的;但重点是Found the pattern 发生在command2 writing 之前,并且也发生在command3 完成之前)。