python paramiko等待完成执行命令

时间:2015-12-09 14:19:17

标签: python paramiko

我在paramiko中写这段代码:

def TryExecute(hostname='192.168.1.1', user='root', passwd='root'):
    ssh = SSHClient()
    ssh.set_missing_host_key_policy(AutoAddPolicy())
    ssh.connect(hostname, username=user, password=passwd, timeout=3)
    #stdin, stdout, stderr =  ssh.exec_command("uname -a")

    session = ssh.invoke_shell()
    session.send("\n")

    session.send("echo step 1\n")
    time.sleep(1)

    session.send("sleep 30\n")
    time.sleep(1)

    while not session.recv_ready():
        time.wait(2)

    output = session.recv(65535)

    session.send("echo step 2\n")
    time.sleep(1)

    output += session.recv(65535)

我尝试在我的linux服务器上执行更多命令,问题是我的python代码不等待完成执行命令,例如,如果我尝试执行“sleep 30”,则python不等待30秒完成执行命令,如何解决这个问题?我在尝试使用白衣,而recv_ready()不等待:(

2 个答案:

答案 0 :(得分:6)

使用exec_commandhttp://docs.paramiko.org/en/1.16/api/channel.html

stdin, stdout, stderr = ssh.exec_command("my_long_command --arg 1 --arg 2")

以下代码适用于我:

from paramiko import SSHClient, AutoAddPolicy
import time
ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect('111.111.111.111', username='myname', key_filename='/path/to/my/id_rsa.pub', port=1123)
sleeptime = 0.001
outdata, errdata = '', ''
ssh_transp = ssh.get_transport()
chan = ssh_transp.open_session()
# chan.settimeout(3 * 60 * 60)
chan.setblocking(0)
chan.exec_command('ls -la')
while True:  # monitoring process
    # Reading from output streams
    while chan.recv_ready():
        outdata += chan.recv(1000)
    while chan.recv_stderr_ready():
        errdata += chan.recv_stderr(1000)
    if chan.exit_status_ready():  # If completed
        break
    time.sleep(sleeptime)
retcode = chan.recv_exit_status()
ssh_transp.close()

print(outdata)
print(errdata)

请注意,无法按原样执行命令history。 请参阅此处的示例:https://superuser.com/questions/962001/incorrect-output-of-history-command-of-ssh-how-to-read-the-timestamp-info-corre

答案 1 :(得分:0)

如果你不需要分别读取stdout和stderr,你可以使用更直接的代码:

stdin, stdout, stderr = ssh_client.exec_command(command)
stdout.channel.set_combine_stderr(True)
output = stdout.readlines()

读取 readlines 直到命令完成并返回完整输出。


如果您需要单独输出,请不要试图删除 set_combine_stderr 并分别在 readlinesstdout 上调用 stderr。那可能会陷入僵局。见Paramiko ssh die/hang with big output

有关单独读取输出的正确代码,请参阅Run multiple commands in different SSH servers in parallel using Python Paramiko


强制性警告:请勿使用 AutoAddPolicy – 这样做您将失去对 MITM attacks 的保护。如需正确的解决方案,请参阅 Paramiko "Unknown Server"