2017-10-09 180 views
1

我試圖從bash/linux下的fifo中讀取一個簡短的python腳本,然後在收到某個單詞時停止。我已經做了以下bash/python從fifo停止讀取

在main.py

import "sys" 
while True: 
    line = sys.stdin.readline().rstrip() 
    sys.stdout.write(line + " read\n") 
    if line=="STOP": 
     break 
sys.stdout.write("finished\n") 

而且我運行這樣的腳本:

mkfifo myfifo 
tail -f myfifo | python main.py 

在另一個shell窗口我輸入:

echo "foobar" > myfifo # "myfifo read" echoed in the other window 
echo "STOP" > myfifo # "finished" echoed in other window 

但是,其他窗口中的進程並不會停止,而是一直保持打開狀態,直到我向myfifo回覆其他內容。

有沒有人知道這裏發生了什麼,以及如何讓python進程退出?

---編輯---

我剛剛改寫main.py作爲一個bash腳本,它有同樣的問題。這似乎是尾-f對此我不熟悉

---另一個編輯的行爲---

如果我搜索Python進程已進入後「STOP」我無法找到它了。這意味着Python進程正在完成。這個問題似乎是tail -f和bash之間的一些相互作用。

---可能最終編輯---

好吧,我想我已經制定了這是怎麼回事,並沒有任何與蟒蛇。

當您對某個命名管道回顯某些內容時,會在末尾添加一個EOFtail -fEOF轉換爲EOL。這意味着如果我不使用tail -f,而是使用cat將命名管道的內容管道化爲python腳本的stdin,則python將在第一行的末尾讀取EOF後失去與stdin的連接。從此,試圖從stdin讀取將導致EOF。出於這個原因,python腳本將顯示無限列表read\n。如果在使用tail -f時python腳本退出,tail -f不知道這些,直到我將其他內容添加到命名管道。

回答

1

tail -f保持打開管無限期,所以你應該叫sys.stdin.close()一旦您完成了從中讀取:

import sys 

while True: 
    line = sys.stdin.readline().rstrip() 
    sys.stdout.write(line + " read\n") 
    if line == "STOP": 
     break 

sys.stdin.close() 
sys.stdout.write("finished\n") 

題外話,但我也改變了你的import "sys"import sys

0

這是尾巴。

./tst.py<myfifo & 

然後發送任何你想要的管道。該代碼正在工作(雖然我不得不脫離我的python版本sys的報價)。你的問題是,尾巴仍然在-f follow模式下運行。

+0

這樣做的麻煩是,如果我然後回聲一些myfifo,python腳本將輸出一個無限列表「讀\ n」。我不知道爲什麼。 – ehrt1974

+0

編輯您的原始文章,以準確顯示您如何設置和執行。除了FIFO之外,不要使用尾部或管道。保持儘可能簡單和最小化。 –