Ho uno script Python che uso per eseguire comandi in parallelo su più host usando il modulo subprocesso Python. Si avvolge SSH, e fondamentalmente fa una chiamata in questo modo:Terminale incasinato (non visualizzava nuove righe) dopo aver eseguito lo script Python
output = subprocess.Popen(["/bin/env", env, "/usr/bin/ssh", "-t", "%[email protected]%s" % (user, host), "--", command], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
Il comando effettivo viene eseguito in questo modo:
/bin/env TERM=$TERM:password /usr/bin/ssh -t "%[email protected]%s" % (user, host), "--", command
Funziona bene, tranne che ottengo un errore intermittente in cui mio terminale viene incasinato (perde newline) dopo aver eseguito lo script. Un "reset" dalla riga di comando lo corregge, ma non sono sicuro di come ciò avvenga, esattamente. Ho notato che a volte c'è uno "\ r \ n" alla fine del primo elemento nell'output della tupla e talvolta non è lì. Vedere il seguente, in particolare "Permesso negato \ 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]
La seconda uscita è stata leggermente modificata, ma mostra dei dispersi "\ r", e come il mio sollecito ottiene "wacked" dopo aver eseguito lo script.
Penso che questo sia correlato all'utilizzo dell'opzione "-t" nel mio comando di sottoprocesso. In qualche modo sto perdendo il \ r. Se rimuovo l'opzione "-t", questo problema scompare, ma per farla breve, ne ho bisogno per passare attraverso le variabili ambientali per l'utilizzo sulla macchina remota (sto usando la variabile TERM per passare la password dell'utente per scopi sudo, perché non posso supporre che AcceptEnv consenta il passaggio di variabili arbitrarie sul server sshd remoto; lo sto facendo per evitare di passare la password sulla riga di comando, che verrà visualizzata nell'elenco dei processi sulla macchina remota).
Basta chiedersi se qualcuno conosce un modo per aggirare questo, senza rimuovere l'opzione "-t"?
UPDATE:. Sembra che le mie impostazioni TTY vengono modificate dopo l'esecuzione del subprocess.Popen (...) comunicare() comando all'interno mio script, indipendentemente dal fatto che ho effettivamente stampare l'output di schermo. Lo trovo davvero strano. Qui ci sono le prima/dopo differenze nella mia TTY config (da -a stty):
-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
Mi chiedo come fermare comunicare() da alterare le impostazioni del terminale? È possibile o è un bug?
il * comando * richiede effettivamente l'opzione '-t' ssh? – jfs
'.communicate()' non modifica le tue impostazioni tty. Prova qualche maledetto script Python che non ripristini le sue impostazioni all'uscita come un * comando * e vedi se è possibile riprodurre l'errore in modo affidabile, ad esempio, fai in modo che lo script accetti un flag sull'opportunità di ripristinare tty all'uscita o meno. Ad esempio, – jfs
, non si può fare nulla nel blocco 'finally' se viene passato un flag' --no-restore' in [questo script] (http://stackoverflow.com/a/327072/4279) – jfs