2013-12-13 28 views
2

不能正常工作,請考慮以下命令:fflush在AWK

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作品。那就是:產生預期的輸出。

回答

3

我們的老朋友strace解決了這個謎。

fflush("cat")情況下,AWK而貓仍在加載快速寫入所有三個值。當貓完成加載時,它會依次讀取所有三個值並同時寫出它們。

close("cat")的情況下,awk等待進程退出,此時cat保證讀取該值,寫入並退出。

我把fflush這個案例中的數字從3增加到1000,現在awk在貓趕上之前達到了120,並且從那裏開始基本按照你的預期工作。它打印「1,2,...,120,1,2,...,120,121,121,122,122,123,123,...」。

請注意,你不能保證看到完美的數字對。 awk阻塞,直到數字寫入管道,但它不會等待貓做任何事情。

1

真的不是我有很多經驗,但GAWK手冊告訴我們:

fflush([文件名]) 刷新與文件名相關的任何緩衝輸出, 這是一個文件打開以寫入或對於 外殼命令重定向輸出到管道或協進程。

請注意,上面使用的「cat」在fawush()影響的gawk手冊中沒有提及。

相同的手冊,另一方面靠近()表示:

關閉(文件名[,如何]) 關閉輸入或輸出的文件的文件名。 可替代地,參數可以是用於創建 一個協,或重定向或從管外殼命令;然後 協處理或管道關閉。

注意,在你使用的貓,上下文從管道重定向等被列入受密切的項目清單()而不是由fflush()。

+1

+1感謝。所以如果你想混合來自'awk'的輸出和來自管道的輸出,你應該總是立即關閉管道(爲了得到正確的輸出)? –

+0

不是我的強項,因爲我不認爲我曾經這麼做過,所以我的意見不值得。抱歉。 –