2017-02-02 39 views
2

我有一個命名管道'timer_fifo',python腳本的標準輸出重定向到timer_fifo,同時另一個shell腳本進程從中讀取,處理它然後將其重定向到另一個名爲'activity_file' 。將stdout重定向到文件顯示錯誤的內容

的Python腳本:

import time 
while True: 
    print(time.strftime('%Y_%m_%d', time.gmtime())) 
    time.sleep(1) 

執行上面的Python腳本:

python above_file_name > timer_fifo 

shell腳本:

while true 
do 
    read action <timer_fifo; 
    echo $action | stdbuf -o0 -e0 -i0 sed -n "s/^\([^[:space:]].*\)/\1 Cinnamon/p" >> activity_file 
done 

注:以上sed的命令追加 '肉桂' 和重定向到活動文件,所以如果輸入是'2017_02_01',那麼它變成'2017_02_01肉桂',它也忽略輸入s如果它是以空間開始的話。

執行上面的shell腳本:

./file_name 

了一段時間的文件的尾部:

2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
2017_02_01 Cinnamon 

但經過一段時間的文件的尾部:

2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
2017_02_01 Cinnamon 
017_02_01 Cinnamon 
207_20 Cinnamon 
270_1 Cinnamon 
210_101_2001_20 Cinnamon 
2017_02_0 Cinnamon 
270_11207_02_01 Cinnamon 
107_20 Cinnamon 
0020 Cinnamon 

正如你看到的,爲什麼輸出會搞砸? 另外我可能不止一次地執行了上面的腳本,所以多個進程同時寫入同一個文件會導致排序輸出?如果有,請解釋原因?

+0

Google上有很多東西,試試吧。 – Marichyasana

+0

這就是我在來這裏之前所做的。 – druuu

回答

0

如果您只運行程序的一個副本,則所有內容都按順序到達fifo,並且緩衝不會影響排序。

如果您運行的程序不止一個副本,並且他們每個人都在執行自己的stdout緩衝,那麼您可以獲得部分行。

我認爲這就是你所看到的。

我認爲在這種情況下(不完全)的解決方案是在你的Python腳本添加print()sleep()之間的線路如下:

sys.stdout.flush() 

這將使它很可能是整個線路將得到寫入fifo的單個不間斷系統調用中,每次調用print()/flush()。它仍然不能確定 - 你不能保證原子性。但在實踐中,這樣的短字符串將作爲單個系統調用進行。

(您也可以嘗試改變sys.stdout的緩衝,或者使用一個運行時標誌蟒蛇,但我認爲作爲上述呼籲flush()是最好的辦法。)

sys.stdout docs:當互動,標準流都行-緩衝的。否則,它們像常規文本文件一樣被塊緩衝

+0

感謝亞歷克斯明確的解釋。 – druuu

+0

不客氣druuu! –

相關問題