2013-01-01 50 views
4

我可能根本沒有正確理解這一點,但我試圖讓Python程序與運行命令的子進程接口,就好像在Linux shell上一樣。Python中的永久終端會話

例如,我希望能夠運行「CD /」,然後「在程序稍後pwd然後得到‘/’。

我目前正在使用subprocess.Popen和溝通()方法來發送和接收數據第一個命令,與Popen構造函數一起發送,運行良好並給出正確的輸出,但是我不能通過通信發送另一個命令(輸入=「pwd」)。

我的代碼到目前爲止:

from subprocess i 
term=Popen("pwd", stdout=PIPE, stdin=PIPE) 
print(flush(term.communicate())) 
term.communicate(input="cd /") 
print(flush(term.communicate(input="pwd"))) 

有沒有更好的方法來做到這一點?謝謝。

另外,我運行的Python 3

+0

使用'os.chdir'方法。 – Keith

+1

那麼這是否意味着我必須爲每個命令創建一個新的Popen對象? – novabrahm

+2

不是。但在這種情況下,'pwd'只是輸出它的輸出並立即退出。沒有一個正在運行的進程與之通信。你確實需要爲每個命令使用fork/exec,這是普通的shell行爲,除非正在構建管道。在那種情況下,你確實需要一個Popen來處理每個命令。 – Keith

回答

0

首先,你要明白,運行shell命令和運行的程序是不一樣的東西。

讓我給你舉個例子:

>>> import subprocess 
>>> subprocess.call(['/bin/echo', '$HOME']) 
$HOME 
0 
>>> subprocess.call(['/bin/echo $HOME'], shell=True) 
/home/kkinder 
0 

注意,沒有外殼= True參數的$HOME文字沒有展開。這是因爲/bin/echo程序不解析$HOME,Bash的確如此。什麼是真正在第二次調用發生的是這個東西類似:

>>> subprocess.call(['/bin/bash', '-c', '/bin/echo $HOME']) 
/home/kkinder 
0 

使用shell=True參數基本上說的子模塊,去解釋使用shell這個文本。

因此,您可以添加shell=True,但問題是一旦命令結束,其狀態將丟失。堆棧中的每個應用程序都有自己的工作目錄。那麼該目錄將是這樣的:

  • 慶典 - /富/酒吧
    • 蟒蛇 - /富
      • 通過子慶典 -/

執行命令後,python進程的路徑保持不變,並且一旦shell完成你的命令。

基本上,你要求的是不實際的。你需要做的是,打開一個管道到Bash,以交互方式提供給你的用戶類型命令,然後以非阻塞的方式讀取輸出。這將涉及複雜的管道,線程等。你確定沒有更好的方法嗎?