I am using paramiko for executing remote commands in python. I want to log the complete remote commandline details to the log file.
e.g. Like using Expect in perl we can log the below commands with its output to a log file
samir@ssahoo-ub-in:~$ cat logfile.txt
samir@ssahoo-ub-in:~$ ls
Desktop Documents Downloads examples.desktop getskype-linux-beta-ubuntu-64 Music Pictures Public Templates Videos VirtualBox VMs
samir@ssahoo-ub-in:~$ hostname
ssahoo-ub-in
samir@ssahoo-ub-in:~$ w
09:11:12 up 10:26, 6 users, load average: 0.05, 0.05, 0.06
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
samir tty7 :0 22:45 10:26m 12:51 0.23s gnome-session --session=classic-gnome
samir pts/0 :0.0 22:46 10:24m 32.80s 14.34s gnome-terminal
samir pts/1 :0.0 23:49 1:03m 0.57s 0.57s bash
samir pts/2 :0.0 07:42 1:22m 0.48s 0.09s vim ../projects /test/test_cases/common/TestHostname.py
samir pts/3 :0.0 08:11 0.00s 0.57s 0.01s w
samir pts/4 :0.0 08:24 46:08 0.21s 0.04s python
samir@ssahoo-ub-in:~$ who
samir tty7 2011-11-10 22:45 (:0)
samir pts/0 2011-11-10 22:46 (:0.0)
samir pts/1 2011-11-10 23:49 (:0.0)
samir pts/2 2011-11-11 07:42 (:0.0)
samir pts/3 2011-11-11 08:11 (:0.0)
samir pts/4 2011-11-11 08:24 (:0.0)
samir@ssahoo-ub-in:~$
I got the above issue resolved by using paramiko.invoke_shell()
e.g.
client = paramiko.SSHClient()
client.load_system_host_keys()
client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
client.set_missing_host_key_policy(AllowAllKeys())
client.connect(HOST, username=USER, password=PASSWORD)
channel = client.invoke_shell()
channel.send("ls -l\n")
while not channel.recv_ready():
time.sleep(2)
results += channel.recv(1024)
But can someone help me in getting the stdout, stderr and return code(exit status) here ?
I tried with recv_stderr and recv_exit_status after invoking shell. But it doesn’t print anything when I tried to print stderr and exit status. Here is my piece of code:
import paramiko, time
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('localhost', username='sam', password='mypassword')
channel = ssh.invoke_shell()
results = ''
results2 = ''
password = 'my_root_password'
try:
channel.send("su -\n")
while not channel.recv_ready():
print "Waiting for root challenge..."
time.sleep(2)
results += channel.recv(1024)
channel.send("%s\n" % password)
while not channel.recv_ready():
print "Authenticating..."
time.sleep(2)
results += channel.recv(1024)
channel.send("ls file_doesnt_exist\n") # Here I am sending a wrong command to fail
if channel.exit_status_ready():
result3 = channel.recv_exit_status(1024)
print "exit status is:", results3 # It doesnt return anything
if channel.recv_stderr_ready():
result2 = channel.recv_stderr(1024)
print results2 # Doesn't print error
except Exception, e:
print e
I am getting some discrepancy in the return code below. May be I am not using in the proper way. Every-time I print the return code, it prints the same as the first one has returned. Do I need to reset the return code. I mean in the following example, I am getting the return code as 2 for both the commands. Now when I interchange both the commands, I mean replace ‘ls -al;exit\n’ with ‘ls -al file_not_exist;exit\n’ and vice versa, it prints return code 0. Each time it prints the same return code as the first one has returned.
channel = client.invoke_shell()
channel.send('ls -al file_not_exist;exit\n') #Sending to list a file which doesn't exist
time.sleep(3)
print "My 1st command exit status is: ",channel.exit_status_ready()
print "My 1st command return code is: ", channel.recv_exit_status()
channel.send('ls -al;exit\n')
time.sleep(3)
print "My 2nd command exit status is: ",channel.exit_status_ready()
print "My 2nd command return code is: ",channel.recv_exit_status()
I need to print the return code of each command. Could you please help me in how to get this issue resolved ?
Looks like from the paramiko.SSHClient docs, you can use the recv_ready and recv return the results of the shell/channel. For example, this worked for me: