当使用Python Paramiko exec_command执行时,一个命令没有完成。

问题描述 投票:1回答:1

我有一个Python程序,它位于远程服务器上,运行时将文件上传到AWS bucket。如果我通过ssh进入服务器,并使用以下命令运行它 sudo python3 /path/to/backup.py 它的工作原理和预期一样。

我正在写一个Python程序来自动化一个更大的过程,其中包括运行backup.py。我使用paramiko库创建了一个函数来完成这个任务。这就是命令被运行的地方

ssh_stdin, ssh_stdout, ssh_stderr = self.ssh.exec_command('sudo python3 /path/to/backup.py', 1800)
logging.debug(f'ssh_stdout: {ssh_stdout.readline()}')
logging.debug(f'ssh_stderr: {ssh_stderr.readline()}')

我的自动化程序给了我这样的输出。

ssh_stdout: Tue, 19 May 2020 14:36:43 INFO     The COS endpoint is 9.11.200.206, writing to vault: SD_BACKUP_4058

之后,程序没有任何动作。当我登录到服务器上,检查以下日志时,我发现 backup.py,我可以看到它还在运行,似乎是停留在文件上传处。这是它卡住的代码。

s3_client.upload_file(
    Filename=BACKUP,
    Bucket=BUCKET_NAME,
    Key=SPLIT_FILE_NAME,
    Callback=pp(BACKUP),
    Config=config)

我不明白为什么当我的自动化程序启动时它会卡在这里 而当我在终端的命令行中运行它时却没有卡在这里 我在日志中看不到任何帮助我的信息。只是在执行过程中似乎卡在了那个点上。会不会是与回调没有得到返回有关?

python python-3.x ssh callback paramiko
1个回答
1
投票

你只能读取一行输出。

logging.debug(f'ssh_stdout: {ssh_stdout.readline()}')

如果远程程序产生了大量的输出,一旦它的输出缓冲区填满,程序就会在下一次尝试写入一些输出时挂起。


如果你想让程序完成,你必须继续读取输出。

最简单的方法是使用 readlinesread:

print(stdout.read())

但这对于像你这样的大型输出来说,效率很低。

相反,你可以逐行读取输出。

for line in stdout:
    print(line.strip())

当命令产生一个错误的输出时,就会变得更复杂, 因为你必须同时读取两个输出流。 参见: Paramiko ssh diehang with big output(大输出).

© www.soinside.com 2019 - 2024. All rights reserved.