更新时间:2022-05-13 05:19:20
sys.stdin.read()
将继续阅读直到 EOF 所以在你的 paramiko 脚本中你需要关闭 stdin
(从 exec_command()
返回).但是如何?
sys.stdin.read()
will keep reading until EOF so in your paramiko script you need to close the stdin
(returned from exec_command()
). But how?
根据 Paramiko 的文档 (v1.16):
According to Paramiko's doc (v1.16):
警告:要正确模拟从套接字的 makefile()
方法创建的文件对象,需要一个 Channel
及其 ChannelFile
应该能够独立关闭或垃圾收集.目前,关闭 ChannelFile
只会刷新缓冲区.
Warning: To correctly emulate the file object created from a socket’s
makefile()
method, aChannel
and itsChannelFile
should be able to be closed or garbage-collected independently. Currently, closing theChannelFile
does nothing but flush the buffer.
stdin.channel.close() 也有问题.
由于 stdin、stdout 和 stderr 都共享一个通道,stdin.channel.close()
也将关闭 stdout 和 stderr 这不是预期的.
stdin.channel.close() also has problem.
Since stdin, stdout and stderr all share one single channel, stdin.channel.close()
will also close stdout and stderr which is not expected.
正确的解决方案是使用 stdin.channel.shutdown_write()
不允许写入通道但仍然允许从通道读取所以 stdout.read()
和stderr.read()
仍然可以工作.
The correct solution is to use stdin.channel.shutdown_write()
which disallows writing to the channel but still allows reading from the channel so stdout.read()
and stderr.read()
would still work.
看下面的例子,看看stdin.channel.close()
和stdin.channel.shutdown_write()
的区别.
See following example to see the difference between stdin.channel.close()
and stdin.channel.shutdown_write()
.
[STEP 101] # cat foo.py
import paramiko, sys, time
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy() )
ssh.connect(hostname='127.0.0.1', username='root', password='password')
cmd = "sh -c 'read v; sleep 1; echo $v'"
stdin, stdout, stderr = ssh.exec_command(cmd)
if sys.argv[1] == 'close':
stdin.write('hello world\n')
stdin.flush()
stdin.channel.close()
elif sys.argv[1] == 'shutdown_write':
stdin.channel.send('hello world\n')
stdin.channel.shutdown_write()
else:
raise Exception()
sys.stdout.write(stdout.read() )
[STEP 102] # python foo.py close # It outputs nothing.
[STEP 103] # python foo.py shutdown_write # This works fine.
hello world
[STEP 104] #