Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

basic paramiko exec_command help

I'm a new paramiko user and am having difficulty running commands on a remote server with paramiko. I want to export a path and also run a program called tophat in the background. I can login fine with paramiko.sshclient() but my code to exec_command has no results.

stdin, stdout, sterr = ssh.exec_command('export PATH=$PATH:/proj/genome/programs
/tophat-1.3.0/bin:/proj/genome/programs/cufflinks-1.0.3/bin:/proj/genome/programs/
bowtie-0.12.7:/proj/genome/programs/samtools-0.1.16')

stdin, stdout, sterr = ssh.exec_command('nohup tophat -o /output/path/directory -I 
10000 -p 8 --microexon-search -r 50 /proj/genome/programs/bowtie-0.12.7/indexes
/ce9 /input/path/1 /input/path/2 &')

there is no nohup.out file and python just goes to the next line with no error messages. I have tried without nohup as well and the result is the same. I was trying to follow this paramiko tutorial.

am I using exec_command incorrectly?

like image 354
pieguy Avatar asked Aug 09 '11 20:08

pieguy


2 Answers

I also ran into the same issue and after looking at this article and this answer, I see the solution is to call the recv_exit_status() method of the Channel. Here is my code:

import paramiko
import time

cli = paramiko.client.SSHClient()
cli.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
cli.connect(hostname="10.66.171.100", username="mapping")
stdin_, stdout_, stderr_ = cli.exec_command("ls -l ~")
# time.sleep(2)    # Previously, I had to sleep for some time.
stdout_.channel.recv_exit_status()
lines = stdout_.readlines()
for line in lines:
    print line

cli.close()

Now my code will be blocked until the remote command is finished. This method is explained here, and please pay some attention to the warning.

like image 52
yaobin Avatar answered Oct 13 '22 11:10

yaobin


exec_command() is non blocking, and it just sends the command to the server then Python will run the following code.

I think you should wait for the command execution ends and do the rest work after that.

"time.sleep(10)" could help which requires "import time". Some examples show that you could read from the stdout ChannelFile object, or simply using stdout.readlines(), it seems to read all the response from the server, guess this could help.

Your code, the above 2 lines of exec_command, they're actually running in different exec sessions. I'm not sure if this has some impact in your case.

I'd suggest you take a look at the demos in the demos folder, they're using Channel class, which has better API to do blocking / nonblocking sending for both shell and exec.

like image 37
terry Avatar answered Oct 13 '22 11:10

terry