gpt4 book ai didi

python - 使用 Paramiko exec_command 运行命令会导致进程在完成之前进入休眠状态

转载 作者:太空狗 更新时间:2023-10-30 00:17:55 34 4
gpt4 key购买 nike

我正在使用 Python 的 Paramiko 模块通过 SSH 连接到远程机器,并使用 Tar/ZIP 压缩一个包含大量文件(超过 14K 文件和 60+g 数据)的文件夹。生成的 zip 本身大约有 10 gig。现在我可以直接从机器运行 zip/tar 命令,没有问题。但是,当我尝试通过 SSHClient.exec_command 运行相同的命令时,它会运行一段时间,但最终远程机器上的压缩进程会进入休眠状态。而 recv_exit_status 只是无限期挂起。这是我正在使用的代码:

stdin, stdout, stderr = ssh.exec_command('cd myDirectory; tar -zcvf output.tgz *')
status = stdout.channel.recv_exit_status()

我也尝试过使用 Zip。

stdin, stdout, stderr = ssh.exec_command('cd myDirectory; find -name "*.gz" | zip output.zip -@')
status = stdout.channel.recv_exit_status()

在这两种情况下,如果我直接从远程机器运行命令,它就会完成压缩/TARing。结果文件就像 9 场演出。但是当我从 Paramiko 尝试它时,它开始了,进行了一半以上(6 次演出),然后过程进入休眠状态!

我已经使用 top 监视了远程机器上的进程,zip/tar 将开始运行,但它最终会在完成之前进入休眠状态。并且 python 脚本将无限期挂起。

知道为什么会这样吗?

最佳答案

可能与超时有关。尝试将 timeout 参数(以秒为单位)添加到调用中:exec_command(timeout=20*60)。这是 20 分钟的示例。有关详细信息,请参阅该方法的文档字符串:

def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False):
"""
Execute a command on the SSH server. A new `.Channel` is opened and
the requested command is executed. The command's input and output
streams are returned as Python ``file``-like objects representing
stdin, stdout, and stderr.

:param str command: the command to execute
:param int bufsize:
interpreted the same way as by the built-in ``file()`` function in
Python
:param int timeout:
set command's channel timeout. See `Channel.settimeout`.settimeout
:return:
the stdin, stdout, and stderr of the executing command, as a
3-tuple

:raises SSHException: if the server fails to execute the command
"""

还有一个我遇到的问题也可能有所贡献:https://github.com/paramiko/paramiko/issues/109

试试我在 https://github.com/paramiko/paramiko/issues/109#issuecomment-111621658 中的建议

我也遇到了这个问题,这是由于 stdout.channel.eof_received == 0

import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("1.1.1.1", username="root", password="pass")
stdin, stdout, stderr = client.exec_command("service XXX start")

stdin、stdout 和 stderr 保持打开状态...

>>> print stdin
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>
>>> print stdout
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>
>>> print stderr
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>

所以没有收到EOF...

>>> print stdin.channel.eof_received
0

通常我收到 True 并且只能使用 stdout.read(),但为了安全起见,我使用了这个解决方法(有效!):WAITING超时,强制执行 stdout.channel.close(),然后执行 stdout.read() :

>>> timeout = 30
>>> import time
>>> endtime = time.time() + timeout
>>> while not stdout.channel.eof_received:
... sleep(1)
... if time.time() > endtime:
... stdout.channel.close()
... break
>>> stdout.read()
'Starting XXX: \n[ OK ]\rProgram started . . .\n'
>>>

关于python - 使用 Paramiko exec_command 运行命令会导致进程在完成之前进入休眠状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13404507/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com