F未在awk中工作的管道上的冲洗

F未在awk中工作的管道上的冲洗,awk,pipe,Awk,Pipe,请考虑以下命令: 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命令在这里不起作用,

请考虑以下命令:

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
却起作用。也就是说:产生预期的输出。

我对这方面的经验并不多,但gawk手册告诉我们:

fflush([filename]) 刷新与文件名关联的任何缓冲输出, 它是一个为写入而打开的文件或一个为写入而打开的shell命令 将输出重定向到管道或协进程

请注意,上面使用的“cat”在gawk手册所述的任何上下文中都不受fflush()的影响

另一方面,close()的同一手册说明:

关闭(文件名[,方式]) 关闭输入或输出的文件名。 或者,该参数可以是用于 创建协进程,或将重定向到管道或从管道重定向到管道;然后 协进程或管道已关闭


请注意,您使用cat的上下文是从管道重定向,因此包含在受close()影响的项目列表中,而不是受fflush()影响的项目列表中。

我对这方面的经验不多,但gawk手册告诉我们:

fflush([filename]) 刷新与文件名关联的任何缓冲输出, 它是一个为写入而打开的文件或一个为写入而打开的shell命令 将输出重定向到管道或协进程

请注意,上面使用的“cat”在gawk手册所述的任何上下文中都不受fflush()的影响

另一方面,close()的同一手册说明:

关闭(文件名[,方式]) 关闭输入或输出的文件名。 或者,该参数可以是用于 创建协进程,或将重定向到管道或从管道重定向到管道;然后 协进程或管道已关闭


请注意,您使用cat的上下文是从管道重定向,因此包含在受close()影响的项目列表中,而不是受fflush()影响的项目列表中。

我们的老朋友
strace
解决了这个谜

fflush(“cat”)
情况下,当cat仍在加载时,awk会快速写入所有三个值。当cat完成加载时,它将按顺序读取所有三个值,并同时将它们写出

close(“cat”)
的情况下,awk等待进程退出,此时cat保证已读取、写入并退出该值

我将
fflush
案例中的数字从3增加到了1000,现在
awk
在cat赶上之前达到了120,从那时起,它的工作基本上与您预期的一样。它打印“1,2,…,120,1,2,…,120121122123123,…”


请注意,不能保证看到完美成对的数字。awk会一直阻塞,直到数字写入管道,但它不会等待cat对其执行任何操作

我们的老朋友
strace
解开了这个谜

fflush(“cat”)
情况下,当cat仍在加载时,awk会快速写入所有三个值。当cat完成加载时,它将按顺序读取所有三个值,并同时将它们写出

close(“cat”)
的情况下,awk等待进程退出,此时cat保证已读取、写入并退出该值

我将
fflush
案例中的数字从3增加到了1000,现在
awk
在cat赶上之前达到了120,从那时起,它的工作基本上与您预期的一样。它打印“1,2,…,120,1,2,…,120121122123123,…”


请注意,不能保证看到完美成对的数字。awk会一直阻塞,直到数字写入管道,但它不会等待cat对其执行任何操作

+1谢谢。因此,如果您想将
awk
的输出与管道的输出混合,您应该始终立即关闭管道(以获得正确的输出)?这不是我的强项,因为我认为我从来没有这样做过,因此我对它的看法没有多大价值。对不起,谢谢。因此,如果您想将
awk
的输出与管道的输出混合,您应该始终立即关闭管道(以获得正确的输出)?这不是我的强项,因为我认为我从来没有这样做过,因此我对它的看法没有多大价值。很抱歉