paramiko exec_command 基础帮助
我刚开始使用paramiko,遇到了一些问题,想在远程服务器上运行命令。我想设置一个路径,并在后台运行一个叫做tophat
的程序。我可以顺利登录,使用paramiko.sshclient()
也没问题,但我用来执行命令的exec_command
却没有任何结果。
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 &')
没有生成nohup.out
文件,Python直接跳到下一行,也没有任何错误信息。我试过不使用nohup
,结果也是一样。我是按照这个paramiko教程来做的。
我是不是用错了exec_command
?
3 个回答
在你运行命令之前,最好先加载一下bash_profile。否则,你可能会遇到“找不到命令”的错误。
比如,我写了一个命令 command = 'mysqldump -uu -pp -h1.1.1.1 -P999 table > table.sql'
,目的是为了导出一个Mysql表。
然后在执行这个导出命令之前,我得手动加载一下bash_profile,方法是输入 . ~/.profile; .~/.bash_profile;
。
示例
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)
exec_command() 是非阻塞的,它只是把命令发送到服务器,然后 Python 会继续执行后面的代码。
我觉得你应该等命令执行完再做其他事情。
可以用 "time.sleep(10)" 来帮忙,这需要先 "import time"。一些例子显示你可以从 ChannelFile 对象中读取输出,或者简单地使用 stdout.readlines(),这似乎可以读取服务器的所有响应,猜测这可能会有帮助。
你的代码中,上面那两行 exec_command 实际上是在不同的执行会话中运行。我不确定这在你的情况下是否会有影响。
我建议你看看 演示文件夹中的示例,它们使用了 Channel 类,这个类有更好的接口来处理阻塞和非阻塞的命令发送,适用于 shell 和 exec。
我也遇到了同样的问题,经过查看这篇文章和这个回答,我发现解决办法是调用Channel的recv_exit_status()
方法。以下是我的代码:
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()
现在我的代码会一直等待,直到远程命令执行完毕。这个方法的详细说明可以在这里找到,请特别注意里面的警告。