我有一個Python腳本,我用它在多個使用Python子流程模塊的主機上並行執行命令。它包裝SSH,並且基本上使得這樣一個電話:運行Python腳本後終端搞砸(不顯示新行)
output = subprocess.Popen(["/bin/env", env, "/usr/bin/ssh", "-t", "%[email protected]%s" % (user, host), "--", command], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
有效命令被這樣執行:
/bin/env TERM=$TERM:password /usr/bin/ssh -t "%[email protected]%s" % (user, host), "--", command
它工作正常,但我得到一個間歇性的錯誤在我的終端得到弄糟(失去換行符)後運行腳本。命令行中的「重置」修復了它,但我不確定這是如何發生的,確切地說。我注意到有時在元組輸出中的第一項的末尾有一個「\ r \ n」,有時它不在那裏。請參閱下,特別是「權限被拒絕\ r \ n」:
**** Okay output ****
[[email protected]/home/user]# ./command.py hosts.lists "grep root /etc/shadow"
Running command "grep root /etc/shadow" on hosts in file "hosts.test"
('grep: /etc/shadow: Permission denied\r\n', 'Connection to server1.example.com closed.\r\n')
('grep: /etc/shadow: Permission denied\r\n', 'Connection to server2.example.com closed.\r\n')
[[email protected]/home/user]#
**** Output causes terminal to not display newlines ****
[[email protected]/home/user]# ./command.py hosts.list "grep root /etc/shadow"
('grep: /etc/shadow: Permission denied\r\n', 'Connection to server1.example.com closed.\r\n')
('grep: /etc/shadow: Permission denied\n', 'Connection to server2.example.com closed.\r\n')
[[email protected]/home/user]# [[email protected]/home/user]# [[email protected]/home/user]
第二輸出已略作修改,但顯示缺少的「\ r」,我的提示如何得到「wacked」在運行腳本之後。
我認爲這與在我的subprocess命令中使用「-t」選項有關。不知怎的,我失去了\ r。如果我刪除了「-t」選項,這個問題就會消失,但長話短說,我需要它來傳遞環境變量以供在遠程機器上使用(我瘋狂地使用TERM變量來傳遞用戶的密碼sudo的目的,因爲我不能假定AcceptEnv允許在遠程sshd服務器上傳遞任意變量;我這樣做是爲了避免在命令行上傳遞密碼,這會在遠程計算機的進程列表中顯示)。
想知道是否有人知道一種方法來解決這個問題,而不刪除「-t」選項?
更新:我的劇本里 它看起來像我的tty設置獲得運行subprocess.Popen(...)後改變通信()命令,不管我是否真正打印輸出屏幕。我覺得很奇怪。這裏有前/在我的TTY配置的差異(從的stty -a)後:
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt
我不知道如何停止改變我的終端設置通信()?這是可能的,還是這是一個錯誤?
* *命令實際上是否需要'-t' ssh選項? – jfs 2014-10-17 21:02:35
'.communicate()'不會改變你的tty設置。嘗試一些curses Python腳本,它不會在退出時將其設置恢復爲*命令*,並查看您是否可以可靠地重現該錯誤,即使腳本接受是否在退出時恢復tty的標誌。 – jfs 2014-10-17 21:06:08
例如,如果在[此腳本](http://stackoverflow.com/a/327072/4279)中傳遞了「--no-restore」標誌,那麼'finally'塊中可以不做任何事情。 – jfs 2014-10-17 21:13:34