pieguy
pieguy

Reputation: 111

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?

Upvotes: 11

Views: 68875

Answers (3)

terry
terry

Reputation: 1587

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.

Upvotes: 10

yaobin
yaobin

Reputation: 2526

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.

Upvotes: 16

Marvin W
Marvin W

Reputation: 3523

You better to load the bash_profile before you run your command. Otherwise you may get a 'command not found' exception.

For example,I write the command command = 'mysqldump -uu -pp -h1.1.1.1 -P999 table > table.sql' in the purpose of dumping a Mysql table

Then I have to load the bash_profile manually before that dumping command by typing . ~/.profile; .~/.bash_profile;.

Example

my_command  = 'mysqldump -uu -pp -h1.1.1.1 -P999 table > table.sql;'

pre_command = """
. ~/.profile;
. ~/.bash_profile;
"""

command = pre_command + my_command

stdin, stdout, stderr = ssh.exec_command(command)

Upvotes: -2

Related Questions