等待远程机器上的Python任务完成

20

我正在Ubuntu上用Python编写一个程序。在该程序中,我试图在完成远程机器(RaspberryPi)上的任务“删除文件”后打印一条消息,该机器已连接到网络。

但是,在实际操作中,打印命令并没有等待远程机器上的任务完成。

有人可以指导我如何做吗? 我的代码如下:

import paramiko

# Connection with remote machine
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.2.34', username='pi', password='raspberry')

filename   = 'fahad.txt'
filedelete ='rm ' + filename
stdin, stdout, stderr = client.exec_command(filedelete)
print ("File Deleted")
client.close()
2个回答

56

这确实是paramiko SSH exec_command(shell script) returns before completion的重复,但那里的答案不是非常详细。所以...

正如您注意到的一样,exec_command是一个非阻塞调用。因此,您必须使用以下方法等待远程命令完成:

在您的特定情况下,您需要后者:

stdin, stdout, stderr = client.exec_command(filedelete)  # Non-blocking call
exit_status = stdout.channel.recv_exit_status()          # Blocking call
if exit_status == 0:
    print ("File Deleted")
else:
    print("Error", exit_status)
client.close()

1
答案原则上是正确的。 但实际实现不可能这么简单,因为如果命令输出足够大,它会发生死锁。请参见Paramiko ssh在输出大量内容时死机/挂起 - Martin Prikryl

6
除了Sylvian Leroux的建议外,如果您的命令涉及运行一个bash脚本,并且需要在paramiko关闭ssh会话后继续运行(每次发送命令时都会发生这种情况),请使用:nohup ./my_bash_script.sh >/dev/null 2>&1nohup告诉系统此进程应忽略收到的“挂起”信号,当ssh会话关闭时发生这种情况。 >/dev/null 2>&&1重定向输出。这是必要的,因为在某些情况下,除非收到输出,否则控制权将不会返回到您的python脚本。
要运行类似“stress”和“vlc”的命令行应用程序并在返回后使它们继续运行,我找到的唯一解决方案是将命令放入bash脚本中,然后跟随&&>/dev/null,然后使用我在前面的段落中提到的方法使用paramiko调用该bash脚本。 这似乎有点“hacky”,但这是我经过数天的搜索后找到的唯一方法。

1
这并没有真正回答问题,但我相信它提供了一些有用的洞见,关于ssh/linux是如何工作的。 - JerodG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接