while 命令后面的命令如何在循环中执行?

while 命令后面的命令如何在循环中执行?
  1. while <command>while 循环的一部分中,<command>每个循环中的执行是否独立于其他循环?
  2. 下面的例子中,为什么while循环可以read一行一行地读取文件的所有行,而没有while循环的while read每次重复时总是读取文件的第一行?

    不使用while循环,可以read一一读取文件的所有行吗?

    $ cat /tmp/tt
    1 2 3 4 5
    6 7 8 9
    10 11
    
    $ cat /tmp/tt | while read tt; do echo $tt; done
    1 2 3 4 5
    6 7 8 9
    10 11
    
    $ cat /tmp/tt | read tt
    $ echo $tt
    1 2 3 4 5
    $ cat /tmp/tt | read tt
    $ echo $tt
    1 2 3 4 5
    

答案1

Q1

while <command>while 循环的一部分中,<command>每个循环中的执行是否独立于其他循环?

是的,<command>将在执行的循环的每个循环中执行while

如果其他循环也消耗输入,则执行多少个循环会受到其他循环的影响stdin。该read命令从 stdin 读取(除非-u n使用 les 选项)。其他一些读取可能会消耗相同的输入,这将影响第一的 while环形。

Q2

一个新的代码,因为你的代码有一个很大的错误[1]

$ cat /tmp/tt | {  read tt; echo "$tt";   }
1 2 3 4 5
$ cat /tmp/tt | {  read tt; echo "$tt";   }
1 2 3 4 5

cat命令将始终从文件的开头开始。
read命令(不带选项设置为( )-d中的其他内容)将获取第一行,并将new line$'\n'exit(导致管道关闭)

while循环中即使存在read,仍然有代码要执行(while)这将使管道保持打开状态从命令中获取下一行cat

$ cat /tmp/tt | while read tt; do echo $tt; done
1 2 3 4 5
6 7 8 9
10 11

[1]你的代码必须干净$tt,尝试unset tt; cat /tmp/tt |{ read tt; echo "$tt"; }确认。

答案2

read当您有两个带有两个输出实例的命令行时cat,按照您使用的方式只能读取第一行,因为 STDIN for 的read第一行始终具有相同的内容。

如果多次读取一只猫输出的内容,您将获得下一行,因为用于读取的 STDIN 不会重置为原始起始行。

$ cat /tmp/tt | ( read tt ; echo $tt )
1 2 3 4 5

$ cat /tmp/tt | ( read tt ; echo $tt ; read tt ; echo $tt )
1 2 3 4 5
6 7 8 9

$ cat /tmp/tt | ( read tt ; echo $tt ; read tt ; echo $tt ; read tt ; echo $tt )
1 2 3 4 5
6 7 8 9
10 11

简而言之:“(A) 如果您read对同一输入 (STDIN) 执行一次、两次和三次,您将得到第一、第二和第三行。(B) 如果执行read多次,但每次都重置输入read,那么您只会多次得到相同的第一行”

更多信息:通过“分组”read实例(在管道的左侧),子 shell 使管道保持打开状态。使用时while,子壳再次保持管道打开。因此,read每次都会读取“下一行”,而不是“第一行”。

相关内容