请考虑以下命令:
bash$ seq 1 3 | awk '{print $0 | "cat"; print "0"}'
0
0
0
1
2
3
bash$ seq 1 3 | awk '{print $0 | "cat"; fflush("cat"); print "0"}'
0
0
0
1
2
3
bash$ seq 1 3 | awk '{print $0 | "cat"; close("cat"); print "0"}'
1
0
2
0
3
0
为什么fflush
命令在这里不起作用,而close
起作用。即:产生预期的输出。
答案 0 :(得分:3)
我们的老朋友strace
解开了这个谜团。
在fflush("cat")
的情况下,当cat仍在加载时,awk会快速写入所有三个值。当cat完成加载时,它会按顺序读取所有三个值并同时将它们写出来。
在close("cat")
的情况下,awk等待进程退出,此时cat保证读取值,写入并退出。
我将fflush
案例中的数字从3增加到1000,现在awk
在猫赶上之前达到120,并且从那里起基本上按照您的预期工作。它打印“1,2,..,120,1,2,...,120,121,121,122,122,123,123,......”。
请注意,您无法保证能够看到完美配对的数字。 awk阻塞,直到数字写入管道,但它不等待猫对它做任何事情。
答案 1 :(得分:1)
不是我经验丰富的东西,但是gawk手册告诉我们:
fflush([文件名]) 刷新与文件名关联的任何缓冲输出, 这是一个为写入而打开的文件或者是一个shell命令 将输出重定向到管道或协同处理。
请注意,上面使用的“cat”并非gawk手册所说的受fflush()影响的上下文。
另一方面,close()的相同手册说:
close(filename [,how]) 关闭输入或输出的文件文件名。 或者,参数可以是用于的shell命令 创建协同进程,或将重定向到管道或从管道重定向;然后 协同处理或管道关闭。
请注意,您使用cat的上下文是重定向来自管道,因此包含在受close()影响但不受fflush()影响的项目列表中。