在bash脚本中多次使用stdin

在bash脚本中多次使用stdin,bash,tee,Bash,Tee,我的脚本接受stdin上的流。不管怎样,我都想将第一行传递给stdout,用-vgrep剩余的行,并将它们传递给stdout 我使用tee解决了一个问题,但我想知道这是否保证总是在grep输出之前打印head的输出?如果在打印任何内容之前,head被某个阻塞了20分钟的内容替换,那么该输出是否会出现在grep输出之后的stdout末尾 tee >(head -n 1) >(tail -n +2 | grep -v -E "$PATTERN") 如果订单没有保证,那么正确的做法是什么

我的脚本接受stdin上的流。不管怎样,我都想将第一行传递给stdout,用
-v
grep剩余的行,并将它们传递给stdout

我使用tee解决了一个问题,但我想知道这是否保证总是在
grep
输出之前打印
head
的输出?如果在打印任何内容之前,
head
被某个阻塞了20分钟的内容替换,那么该输出是否会出现在
grep
输出之后的stdout末尾

tee >(head -n 1) >(tail -n +2 | grep -v -E "$PATTERN")

如果订单没有保证,那么正确的做法是什么?

您想得太多了,不需要
tee
head
tail

您可以使用
read
使用第一行并将其打印出来,然后在其余部分使用
grep

$ printf "foo\nbar\nquux\n" | { read v; echo "$v"; grep -v bar; }
foo
quux
或者,将逻辑组合成单个
awk
语句,并完全避免问题:

$ printf "foo\nbar\nquux\n" | awk 'NR==1{print;next} !/bar/'
foo
quux

你偏执是对的。两个子壳将并行运行,因此不能保证其中一个子壳将先于另一个子壳运行。要强制执行操作顺序,请先读取并打印第一行,然后再grep其他输入

read line && printf '%s\n' "$line"
tee >(grep -v -E "$PATTERN")

我想我应该选择
sed

printf "Line1\nfoo\nbar\n" | sed '1n;/bar/d'
输出:

Line1
foo

那就是说。。。如果是第1行打印并转到下一行,否则如果该行包含
,请将其删除。

为什么不尝试它?两个进程替换的一个更明显的问题是,尽管
只输出一行,但它很可能读取大于一个字节的块以找到第一个换行,因此,可能会消耗更多的信息,而不仅仅是第一行。酷,是的,在这种情况下使用read是有意义的。我想我对这个问题的解决方案总的来说很好奇(我不能用read替换其中一个)。