我有一个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)
我不明白为什么当我的自动化程序启动时它会卡在这里 而当我在终端的命令行中运行它时却没有卡在这里 我在日志中看不到任何帮助我的信息。只是在执行过程中似乎卡在了那个点上。会不会是与回调没有得到返回有关?
你只能读取一行输出。
logging.debug(f'ssh_stdout: {ssh_stdout.readline()}')
如果远程程序产生了大量的输出,一旦它的输出缓冲区填满,程序就会在下一次尝试写入一些输出时挂起。
如果你想让程序完成,你必须继续读取输出。
最简单的方法是使用 readlines
或 read
:
print(stdout.read())
但这对于像你这样的大型输出来说,效率很低。
相反,你可以逐行读取输出。
for line in stdout:
print(line.strip())
当命令产生一个错误的输出时,就会变得更复杂, 因为你必须同时读取两个输出流。 参见: Paramiko ssh diehang with big output(大输出).