我试图了解UNIX Shell,“ read”命令使我感到困惑。如以下代码段(或“ while-read”惯用语)所示,此命令“占用”一行标准输入。
(read -r foo ; echo '*** Before cat ***' ; cat) << 'END'
hello
world
END
输出:
*** Before cat ***
world
我的问题如下:
答案 0 :(得分:0)
虽然Nothing
一次只能可靠地读取一行,但让我们看一下其他三个普通命令的消耗量。 read
仅打印第一行。但是,这样做会消耗stdin的8192字节:
head -1
命令$ seq 5000 | tee >(wc >/dev/tty) | ( head -1 >/dev/null; cat) | wc
5000 5000 23893
3141 3140 15701
$ echo $((23893 - 15701))
8192
应该读取第一行并退出。但是,为此,它消耗了4096个字节的stdin:
awk '{exit}'
$ seq 5000 | tee >(wc >/dev/tty) | ( awk '{exit}' >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
应该在读取的第一行中退出,但它也会消耗4096字节的stdin:
sed 1q
数量8192和4096在当前代码中似乎是缓冲区大小。可能希望这些大小可以从一个版本更改为下一个版本。
$ seq 5000 | tee >(wc >/dev/tty) | ( sed 1q >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
是一种实用程序,可尝试控制命令使用的缓冲区大小。 stdbuf
尝试将输入中的缓冲区大小设置为1个字节。应用stdbuf后,stdbuf -i1
仅消耗一行:
sed 1q
使用$ (echo First; echo Second) | ( stdbuf -i1 sed 1q>/dev/null; cat)
Second
作为输入,它仍然只消耗一行:
seq
同一技巧不适用于$ seq 5000 | tee >(wc >/dev/tty) | ( stdbuf -i1 sed 1q >/dev/null; cat) | wc
5000 5000 23893
4999 4999 23891
或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
的外壳一次仅可靠消耗一行,但是外部命令(例如read
,sed
和awk
)消耗的是实现相关的数量即使处理一行时也是如此。
要回答您的两个问题:
在当前实现中,可以使用head
仅消耗一行stdbuf,但是似乎没有保证在任何将来的版本中都可以继续使用。
stdbuf -i1 sed 1q
的示例表明,可以编写一种实用程序来关闭输入缓冲,因此仅消耗所需的stdin。