Linux head 实用程序只读取一行需要更多的输入才能退出



我需要逐行从连续数据流(实际上是管道)中读取,并且我需要在第 1 行之后退出。就在第一行之后。听起来很简单,但是使用"head -n 1",我注意到我实际上需要在 head 退出之前输入第二行。

测试用例:

[s@svr1 ~]$ cat | head -n 1    
123    <- I type this first (followed by enter, of course)
123    <- I get this output from head, but the command does no exit
456    <- Then I need to type this for the command to exit and bring me back to the prompt
[s@svr1 ~]$

有人可以解释(首先)为什么它会那样做,也许我如何才能得到我需要的东西?(我想坚持基本的 Linux/Unix 轻量级构建块。没有Perl,Python之类的...

谢谢

因为你使用的是cat | head -n 1,这是对cat的无用用,与head -n 1不同。如果你在控制台上head -n 1,你会得到你想要的行为 - head读取一行,打印它,然后退出。

如果您执行cat | head -n 1,则会发生以下情况:

  1. cat从其输入中读取"123"。
  2. cat将"123"写入其输出。
  3. head从其输入(连接到cat的输出)读取"123"。
  4. head将"123"写入其输出并退出。
  5. cat从其输入中读取"456"。
  6. cat尝试将"456"写入其输出。
  7. cat之所以SIGPIPE,是因为其输出另一端的进程已经死亡。
  8. cat退出。

cat一写"123"就开始另一次读取head,直到它试图写第二行,它才发现head已经死了。

您可以使用 control-d 关闭管道。然后刷新输出缓冲区,磁头获得EOF并在获得更多输入之前退出。

[s@svr1 ~]$ 猫 | 头 -n 1
123
123
控制-D
[s@svr1 ~]$

head阅读第一行后停止。您可以通过以下方式进行验证

[s@svr1 ~]$ 猫 | 头 -n 1

然后做一个ps aux | grep -w -e cat -e head,得到

。 猫
... 头
... grep -e cat -e head

然后输入

123
123

然后再次执行ps aux | grep -w -e cat -e head,结果为

。 猫
... grep -e cat -e head

瞧,头不见了。所以它不是头徘徊,而是猫在收到 EPIPE 后中止,当它试图写第二行时。

有人可以解释(首先也是最重要的)为什么它会那样做吗?

当未指定文件名时,cat使用STDIN - 因此它正在等待您为其提供第二行或^D。

您可以使用 sed -n 1p filename仅抓取第一行,sed '1!d' filename删除除第一行之外的所有内容。

最新更新