I have a Python script that I use to execute commands in parallel on multiple nodes using the Python subprocess module. It wraps SSH and basically makes the call like this:
output = subprocess.Popen(["/bin/env", env, "/usr/bin/ssh", "-t", "% s@ %s" % (user, host), "--", command], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
An effective command is executed as follows:
/bin/env TERM=$TERM:password /usr/bin/ssh -t "% s@ %s" % (user, host), "--", command
It works fine, except that I get an intermittent error when my terminal gets messed up (loses new lines) after running the script. "reset" from the command line fixes it, but I'm not sure how this happens. I noticed that sometimes there is "\ r \ n" at the end of the first element in the tuple, and sometimes not. See the following, in particular " Permission denied \ r \ n" :
**** Okay output **** [ user@ /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') [ user@ /home/user]# **** Output causes terminal to not display newlines **** [ user@ /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') [ user@ /home/user]# [ user@ /home/user]# [ user@ /home/user]
The second output has been slightly modified, but shows the missing "\ r" and how my prompt gets "wacked" after running the script.
I think this is due to the use of the -t option in my subprocess command. Somehow I'm losing. If I remove the "-t" option, this problem will disappear, but I will need a long history to go through the environment variables for use on the remote machine (I hackerily use the TERM variable to go through the user password for sudo, because I cannot assume that AcceptEnv allows you to pass an arbitrary variable to the remote sshd server, I do this so as not to skip the password on the command line, which will be displayed in the list of processes on the remote machine).
Just wondering if anyone knows a way around this without removing the -t option?
UPDATE: It seems that the tty settings are changing after running the subprocess.Popen (...) command . Communication () in my script, regardless of whether I really print the output to the screen. I find it really strange. Here are the differences before and after my tty config (from 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
I am wondering how to disconnect communication () from changing terminal settings? Is this possible, or is it a mistake?