如何在 paramiko 中写入标准输入(从 exec_command 返回)?
How do I write to stdin (returned from exec_command) in paramiko?
我正在尝试使用 paramiko 写入自定义程序的标准输入。这是一个最小的(非)工作示例:
~/stdin_to_file.py:
#! /usr/bin/python
import time, sys
f = open('/home/me/LOG','w')
while True:
sys.stdin.flush()
data = sys.stdin.read()
f.write(data+'\n\n')
f.flush()
time.sleep(0.01)
然后我在 IPython 中执行这些命令:
import paramiko
s = paramiko.client.SSHClient
s.load_system_host_keys()
s.connect('myserver')
stdin, stdout, stderr = s.exec_command('/home/me/stdin_to_file.py')
stdin.write('Hello!')
stdin.flush()
不幸的是,~/LOG 中什么也没有出现。但是,如果我这样做
$ ~/stdin_to_file.py < some_other_file
some_other_file的内容出现在~/LOG.
谁能指出我哪里出错了?看来我在做合乎逻辑的事情。 None 这些作品之一:
stdin.channel.send('hi')
using the get_pty parameter
sending the output of cat - to stdin_to_file.py
sys.stdin.read()
将继续阅读直到 EOF,因此在您的 paramiko 脚本中您需要关闭 stdin
(从 exec_command()
返回)。但是怎么办?
1。 stdin.close()
不行。
根据 Paramiko 的文档 (v1.16):
Warning: To correctly emulate the file object created from a socket’s makefile()
method, a Channel
and its ChannelFile
should be able to be closed or garbage-collected independently. Currently, closing the ChannelFile
does nothing but flush the buffer.
2。 stdin.channel.close() also has problem.
由于 stdin、stdout 和 stderr 都共享一个通道,stdin.channel.close()
也将关闭 stdout 和 stderr 这不是预期的。
3。 stdin.channel.shutdown_write()
正确的解决方案是使用 stdin.channel.shutdown_write()
,它不允许写入通道但仍允许从通道读取,因此 stdout.read()
和 stderr.read()
仍然有效。
请参阅以下示例以了解 stdin.channel.close()
和 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] #
我正在尝试使用 paramiko 写入自定义程序的标准输入。这是一个最小的(非)工作示例:
~/stdin_to_file.py:
#! /usr/bin/python
import time, sys
f = open('/home/me/LOG','w')
while True:
sys.stdin.flush()
data = sys.stdin.read()
f.write(data+'\n\n')
f.flush()
time.sleep(0.01)
然后我在 IPython 中执行这些命令:
import paramiko
s = paramiko.client.SSHClient
s.load_system_host_keys()
s.connect('myserver')
stdin, stdout, stderr = s.exec_command('/home/me/stdin_to_file.py')
stdin.write('Hello!')
stdin.flush()
不幸的是,~/LOG 中什么也没有出现。但是,如果我这样做
$ ~/stdin_to_file.py < some_other_file
some_other_file的内容出现在~/LOG.
谁能指出我哪里出错了?看来我在做合乎逻辑的事情。 None 这些作品之一:
stdin.channel.send('hi')
using the get_pty parameter
sending the output of cat - to stdin_to_file.py
sys.stdin.read()
将继续阅读直到 EOF,因此在您的 paramiko 脚本中您需要关闭 stdin
(从 exec_command()
返回)。但是怎么办?
1。 stdin.close()
不行。
根据 Paramiko 的文档 (v1.16):
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.
2。 stdin.channel.close() also has problem.
由于 stdin、stdout 和 stderr 都共享一个通道,stdin.channel.close()
也将关闭 stdout 和 stderr 这不是预期的。
3。 stdin.channel.shutdown_write()
正确的解决方案是使用 stdin.channel.shutdown_write()
,它不允许写入通道但仍允许从通道读取,因此 stdout.read()
和 stderr.read()
仍然有效。
请参阅以下示例以了解 stdin.channel.close()
和 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] #