默认行为
而
read
可靠地一次只读取一行,让我们看看其他三个常见命令消耗了多少。
head -1
只打印第一行。但是,要做到这一点,它从stdin消耗8192个字节:
$ seq 5000 | tee >(wc >/dev/tty) | ( head -1 >/dev/null; cat) | wc
5000 5000 23893
3141 3140 15701
$ echo $((23893 - 15701))
8192
</code>
命令
awk ‘{exit}’
应阅读第一行并退出。但是,要做到这一点,它会占用4096字节的stdin:
$ seq 5000 | tee >(wc >/dev/tty) | ( awk ‘{exit}’ >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
</code>
sed 1q
应该在第一行读取时退出,但它也消耗4096字节的stdin:
$ seq 5000 | tee >(wc >/dev/tty) | ( sed 1q >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
</code>
数量8192和4096似乎是当前代码中的缓冲区大小。可以预期这些尺寸可能会从一个版本更改为下一个版本。
使用stdbuf
stdbuf
是试图控制命令使用的缓冲区大小的实用程序。
stdbuf -i1
尝试将输入中的缓冲区大小设置为1个字节。使用stdbuf,
sed 1q
只消耗一行:
$ (echo First; echo Second) | ( stdbuf -i1 sed 1q>/dev/null; cat)
Second
</code>
同
seq
作为输入,它仍然只消耗一行:
$ seq 5000 | tee >(wc >/dev/tty) | ( stdbuf -i1 sed 1q >/dev/null; cat) | wc
5000 5000 23893
4999 4999 23891
</code>
这同样的伎俩不起作用
head
要么
awk
。尽管如此,这两种方法都会消耗几个kB
stdbuf
:
$ seq 5000 | tee >(wc >/dev/tty) | ( stdbuf -i1 head -1 >/dev/null; cat) | wc
5000 5000 23893
3141 3140 15701
$ echo $((23893 - 15701))
8192
$ seq 5000 | tee >(wc >/dev/tty) | ( stdbuf -i1 awk ‘{exit}’ >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
</code>
摘要
虽然壳内置
read
可靠地一次仅消耗一行,外部命令,如
sed
,
awk
,和
head
,即使在处理单行时,也会消耗依赖于实现的stdin量。
回答你的两个问题:
在当前的实现中,可以只使用一行stdbuf
stdbuf -i1 sed 1q
但似乎没有任何保证,这将继续适用于任何未来的版本。
的例子
stdbuf -i1 sed 1q
表示可以编写一个关闭输入缓冲的实用程序,因此只消耗所需的stdin。
</醇>