gpt4 book ai didi

bash - 'while head -n 1' 好奇心

转载 作者:行者123 更新时间:2023-11-29 09:27:35 24 4
gpt4 key购买 nike

一些编码实验(在尝试找到编码问题的较短答案时进行的)导致了一些有趣的惊喜:

seq 2 | while head -n 1 ; do : ; done

输出(点击 Control-C 否则它将永远浪费 CPU 周期):

1
^C

相同,但使用重定向输入文件而不是管道输入:

seq 2 > two
while head -n 1 ; do : ; done < two

输出(点击 Control-C):

1
2
^C

问题:

  1. 为什么 while 循环不停止 seq 2 | head -n 1 会吗?

  2. 为什么重定向输入管道输入产生更多输出?

    /li>

以上代码在最近的 Lubuntu 上用 dashbash 进行了测试。 seqhead 都来自 coreutils(版本 8.25-2ubuntu2)包。

绕过必须按 (Ctrl-C) 的方法:

timeout .1 sh -c "seq 2 > two ; while head -n 1 ; do : ; done < two"

1
2

timeout .1 sh -c "seq 2 | while head -n 1 ; do : ; done"

1

最佳答案

head -n 1,当在 stdin 上给定一个空流时,完全符合其权利和规范,可以立即以成功退出状态退出。

因此:

seq 2 | while head -n 1 ; do : ; done

...可以合法地永远循环,因为 head -n 1 不需要以非零状态退出并因此终止循环。 (只有在“发生错误”时,标准才需要非零退出状态,并且文件行数少于输出请求的行数不被定义为错误)。

确实,这是明确的:

When a file contains less than number lines, it shall be copied to standard output in its entirety. This shall not be an error.


现在,如果您的 head 实现在第一次调用后(打印第一行的内容),使文件指针在第二行当它退出时(绝对不需要这样做),然后第二个循环实例将读取第二行并发出它。然而,这又是一个实现细节,它取决于编写您的 head 实现的人是否选择任一个:

  1. 读取一个非常大的 block ,但只发出它的一个子集。 (更有效的实现。)
  2. 逐个字符地循环以仅使用一行。

实现者完全有权根据仅在运行时可用的标准来决定要遵循哪些实现。


现在,假设您的总是尝试一次读取 8kb block 。那么,它怎么能让指针在第二行排队呢? [* - 除了向后查找,some implementations do当给定文件时,但标准不需要;感谢 Rob Mayhoff 在这里指点]

如果 seq 的并发调用在第一个 read 发生时仅写入并刷新了一行,则可能会发生这种情况。

显然,这是一种对时间非常敏感的情况——竞争条件——并且还取决于未指定的实现细节,(seq 是否在行之间刷新其输出——这作为 seq 未指定为 POSIX 或任何其他标准的一部分,在平台之间完全不同。

关于bash - 'while head -n 1' 好奇心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37861360/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com