我正在使用以下代码:
import paramiko
def runSshCmd(hostname, username, password, cmd, timeout=None):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname, username=username, password=password,
allow_agent=False, look_for_keys=False, timeout=timeout)
stdin, stdout, stderr = client.exec_command(cmd)
stdin.flush()
data = stdout.read()
print (data)
client.close()
runSshCmd("10.128.12.32", "root", "C0mput3Gr!d", "ts_menu")
当涉及到 stdout.read() 时,它挂起...有时它会在很长时间后打印输出。
您能否建议是否可以对此问题采取任何措施?
我看到此问题已在 中报告:
https://bugs.python.org/issue24026
python 中有没有更好的模块用于 ssh 连接和运行命令?
可能与 https://github.com/paramiko/paramiko/issues/109 有关
以下是我面临的问题以及我如何解决它的说明。
我也遇到了这个问题,这是由于 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(),但为了安全起见,我使用此解决方法(有效!等待超时,强制 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 2.6.6
paramiko (1.15.2)
希望这有帮助...
我碰巧遇到了这个问题。但我通过使用"readline"而不是"readlines"来解决它。
例如:
client = paramiko.SSHClient()
client.connect(addr, port, username, password)
stdin, stdout, stderr = client.exec_command(cmd)
while True:
print(stdout.readline())
if stdout.channel.exit_status_ready():
break
因此,它将立即打印每一行并且不再挂起,并且 exit_status_ready() 将确保在 stdout 停止/退出时循环中断。
当 stdout 中没有数据或有一行没有 eol 时(即在 sh 脚本内的 read 语句中),就会发生这种情况。尝试设置"get_pty=True",然后仅读取标准输出中的字节。为了避免无限循环,尽管有 continue 语句,最好设置超时和睡眠:
stdin, stdout, stderr = ssh.exec_command("your-command",get_pty=True)
stdout.flush()
nbytes = 0
while (len(stdout.channel.in_buffer)==0):
continue
nbytes=len(stdout.channel.in_buffer)
print(nbytes)
stdout.read(nbytes)
尝试在使用 stdout 之前关闭 stdin。
环境:
python3.8
帕拉米科-2.7.2
stdin, stdout, stderr = client.exec_command(cmd)
stdin.close()
for line in iter(stout.readline,""):
print(line, end='')
对于仍在为此苦苦挣扎的人:我能够通过在尝试读取stdout
或stderr
之前运行client.close()
来解决此问题。
如果你期望在命令完成时有一个特定的输出,你可以删除数据 = stdout.read() 并写这个
while True:
if "Ended" in str(stdout.readline()):
stdout.channel.close()
break
在我的情况下,我的命令会返回"结束"的内容,所以我会检查它,如果是,则执行 stdout.channel.close() 这解决了我的问题。在您的情况下,"已结束"可以是您希望获得的任何内容