Python : Paramiko - channel.exec_command 不间歇性地返回输出
Python : Paramiko - channel.exec_command not returning output intermittently
我在使用 Paramiko 执行远程操作时遇到间歇性问题。
if channel.active:
contents = io.StringIO()
error = io.StringIO()
try:
LOG.info('{} - Executing script {} - as {} user '.format(self.target_host, script, self.targetvmuser))
channel.exec_command(script)
while not channel.exit_status_ready():
if channel.recv_ready():
data = channel.recv(1024)
LOG.debug(data.decode())
while data:
contents.write(data.decode())
data = channel.recv(1024)
LOG.debug(data.decode())
if channel.recv_stderr_ready():
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
while error_buff:
error.write(error_buff.decode())
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
exit_status = channel.recv_exit_status()
下面是2次执行的调试日志。我无法弄清楚为什么下面的输出在一个 VM 上返回,而在另一个 VM 上却没有。
2022-03-17 12:14:42 [DEBUG] - -rw-rw-r--. 1 test test 1702 Mar 17 12:14 /tmp/testfile
2022-03-17 12:14:42 [DEBUG] -
Linux 带有 Paramiko 2.7.2 的虚拟机 - 间歇性错误 运行。
2022-03-17 12:14:20 [DEBUG][chan 0] Max packet out: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - Secsh channel 0 opened.
2022-03-17 12:14:20 [DEBUG] - [chan 1] Max packet in: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - [chan 1] Max packet out: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - Secsh channel 1 opened.
2022-03-17 12:14:20 [DEBUG] - [chan 1] Sesch channel 1 request ok
2022-03-17 12:14:20 [INFO ] - [chan 1] Opened sftp connection (server version 3)
2022-03-17 12:14:20 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb')
2022-03-17 12:14:20 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:20 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb') -> 00000000
2022-03-17 12:14:20 [DEBUG] - [chan 1] close(00000000)
2022-03-17 12:14:20 [DEBUG] - [chan 1] stat(b'/tmp/testfile')
2022-03-17 12:14:20 [DEBUG] - [chan 2] Max packet in: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - [chan 2] Max packet out: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - Secsh channel 2 opened.
2022-03-17 12:14:20 [INFO ] - 10.9.59.11 - Executing script ls -ltr /tmp/testfile - as opc user
2022-03-17 12:14:20 [DEBUG] - [chan 2] Sesch channel 2 request ok
2022-03-17 12:14:20 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:20 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:20 [DEBUG] - [chan 2] EOF received (2)
2022-03-17 12:14:20 [DEBUG] - [chan 2] EOF sent (2)
2022-03-17 12:14:20 [INFO ] - 10.9.59.11 -script ls -ltr /tmp/testfile 0 - exit code is 0
2022-03-17 12:14:20 [INFO ] - [chan 1] sftp session closed.
2022-03-17 12:14:20 [DEBUG] - [chan 1] EOF sent (1)
2022-03-17 12:14:20 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:20 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:20 [DEBUG] - EOF in transport thread
Linux VM with Paramiko 2.9.2 & Windows – Paramiko 2.7.2 – 没有问题 – 总是好的 运行.
2022-03-17 12:14:42 [DEBUG] - [chan 0] Max packet out: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Secsh channel 0 opened.
2022-03-17 12:14:42 [DEBUG] - [chan 1] Max packet in: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - [chan 1] Max packet out: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Secsh channel 1 opened.
2022-03-17 12:14:42 [DEBUG] - [chan 1] Sesch channel 1 request ok
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [INFO ] - [chan 1] Opened sftp connection (server version 3)
2022-03-17 12:14:42 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb')
2022-03-17 12:14:42 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb') -> 00000000
2022-03-17 12:14:42 [DEBUG] - [chan 1] close(00000000)
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [DEBUG] - [chan 1] stat(b'/tmp/testfile')
2022-03-17 12:14:42 [DEBUG] - [chan 2] Max packet in: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [DEBUG] - [chan 2] Max packet out: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Secsh channel 2 opened.
2022-03-17 12:14:42 [INFO ] - 10.9.59.11 - Executing script ls -ltr /tmp/testfile - as test user
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [DEBUG] - [chan 2] Sesch channel 2 request ok
2022-03-17 12:14:42 [DEBUG] - [chan 2] EOF received (2)
2022-03-17 12:14:42 [DEBUG] - [chan 2] EOF sent (2)
2022-03-17 12:14:42 [DEBUG] - -rw-rw-r--. 1 test test 1702 Mar 17 12:14 /tmp/testfile
2022-03-17 12:14:42 [DEBUG] -
2022-03-17 12:14:42 [INFO ] - 10.9.59.11 -script ls -ltr /tmp/testfile 0 - exit code is 0
2022-03-17 12:14:42 [INFO ] - [chan 1] sftp session closed.
2022-03-17 12:14:42 [DEBUG] - [chan 1] EOF sent (1)
2022-03-17 12:14:42 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:42 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:42 [DEBUG] - EOF in transport thread
这可能是竞争条件。如果命令已完成,exit_status_ready
可以 return 为真,即使您还没有阅读它的完整输出。
正确的代码如下:
while True:
exited = channel.exit_status_ready()
if channel.recv_ready():
data = channel.recv(1024)
LOG.debug(data.decode())
while data:
contents.write(data.decode())
data = channel.recv(1024)
LOG.debug(data.decode())
if channel.recv_stderr_ready():
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
while error_buff:
error.write(error_buff.decode())
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
if exited:
break
我在使用 Paramiko 执行远程操作时遇到间歇性问题。
if channel.active:
contents = io.StringIO()
error = io.StringIO()
try:
LOG.info('{} - Executing script {} - as {} user '.format(self.target_host, script, self.targetvmuser))
channel.exec_command(script)
while not channel.exit_status_ready():
if channel.recv_ready():
data = channel.recv(1024)
LOG.debug(data.decode())
while data:
contents.write(data.decode())
data = channel.recv(1024)
LOG.debug(data.decode())
if channel.recv_stderr_ready():
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
while error_buff:
error.write(error_buff.decode())
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
exit_status = channel.recv_exit_status()
下面是2次执行的调试日志。我无法弄清楚为什么下面的输出在一个 VM 上返回,而在另一个 VM 上却没有。
2022-03-17 12:14:42 [DEBUG] - -rw-rw-r--. 1 test test 1702 Mar 17 12:14 /tmp/testfile
2022-03-17 12:14:42 [DEBUG] -
Linux 带有 Paramiko 2.7.2 的虚拟机 - 间歇性错误 运行。
2022-03-17 12:14:20 [DEBUG][chan 0] Max packet out: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - Secsh channel 0 opened.
2022-03-17 12:14:20 [DEBUG] - [chan 1] Max packet in: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - [chan 1] Max packet out: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - Secsh channel 1 opened.
2022-03-17 12:14:20 [DEBUG] - [chan 1] Sesch channel 1 request ok
2022-03-17 12:14:20 [INFO ] - [chan 1] Opened sftp connection (server version 3)
2022-03-17 12:14:20 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb')
2022-03-17 12:14:20 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:20 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb') -> 00000000
2022-03-17 12:14:20 [DEBUG] - [chan 1] close(00000000)
2022-03-17 12:14:20 [DEBUG] - [chan 1] stat(b'/tmp/testfile')
2022-03-17 12:14:20 [DEBUG] - [chan 2] Max packet in: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - [chan 2] Max packet out: 32768 bytes
2022-03-17 12:14:20 [DEBUG] - Secsh channel 2 opened.
2022-03-17 12:14:20 [INFO ] - 10.9.59.11 - Executing script ls -ltr /tmp/testfile - as opc user
2022-03-17 12:14:20 [DEBUG] - [chan 2] Sesch channel 2 request ok
2022-03-17 12:14:20 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:20 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:20 [DEBUG] - [chan 2] EOF received (2)
2022-03-17 12:14:20 [DEBUG] - [chan 2] EOF sent (2)
2022-03-17 12:14:20 [INFO ] - 10.9.59.11 -script ls -ltr /tmp/testfile 0 - exit code is 0
2022-03-17 12:14:20 [INFO ] - [chan 1] sftp session closed.
2022-03-17 12:14:20 [DEBUG] - [chan 1] EOF sent (1)
2022-03-17 12:14:20 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:20 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:20 [DEBUG] - EOF in transport thread
Linux VM with Paramiko 2.9.2 & Windows – Paramiko 2.7.2 – 没有问题 – 总是好的 运行.
2022-03-17 12:14:42 [DEBUG] - [chan 0] Max packet out: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Secsh channel 0 opened.
2022-03-17 12:14:42 [DEBUG] - [chan 1] Max packet in: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - [chan 1] Max packet out: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Secsh channel 1 opened.
2022-03-17 12:14:42 [DEBUG] - [chan 1] Sesch channel 1 request ok
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [INFO ] - [chan 1] Opened sftp connection (server version 3)
2022-03-17 12:14:42 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb')
2022-03-17 12:14:42 [DEBUG] - [chan 1] open(b'/tmp/testfile', 'wb') -> 00000000
2022-03-17 12:14:42 [DEBUG] - [chan 1] close(00000000)
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [DEBUG] - [chan 1] stat(b'/tmp/testfile')
2022-03-17 12:14:42 [DEBUG] - [chan 2] Max packet in: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [DEBUG] - [chan 2] Max packet out: 32768 bytes
2022-03-17 12:14:42 [DEBUG] - Secsh channel 2 opened.
2022-03-17 12:14:42 [INFO ] - 10.9.59.11 - Executing script ls -ltr /tmp/testfile - as test user
2022-03-17 12:14:42 [DEBUG] - Sending global request "keepalive@lag.net"
2022-03-17 12:14:42 [DEBUG] - [chan 2] Sesch channel 2 request ok
2022-03-17 12:14:42 [DEBUG] - [chan 2] EOF received (2)
2022-03-17 12:14:42 [DEBUG] - [chan 2] EOF sent (2)
2022-03-17 12:14:42 [DEBUG] - -rw-rw-r--. 1 test test 1702 Mar 17 12:14 /tmp/testfile
2022-03-17 12:14:42 [DEBUG] -
2022-03-17 12:14:42 [INFO ] - 10.9.59.11 -script ls -ltr /tmp/testfile 0 - exit code is 0
2022-03-17 12:14:42 [INFO ] - [chan 1] sftp session closed.
2022-03-17 12:14:42 [DEBUG] - [chan 1] EOF sent (1)
2022-03-17 12:14:42 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:42 [DEBUG] - [chan 0] EOF sent (0)
2022-03-17 12:14:42 [DEBUG] - EOF in transport thread
这可能是竞争条件。如果命令已完成,exit_status_ready
可以 return 为真,即使您还没有阅读它的完整输出。
正确的代码如下:
while True:
exited = channel.exit_status_ready()
if channel.recv_ready():
data = channel.recv(1024)
LOG.debug(data.decode())
while data:
contents.write(data.decode())
data = channel.recv(1024)
LOG.debug(data.decode())
if channel.recv_stderr_ready():
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
while error_buff:
error.write(error_buff.decode())
error_buff = channel.recv_stderr(1024)
LOG.debug(error_buff.decode())
if exited:
break