如何在Python中在远程服务器上执行命令并将stdout传递给本地命令?要在Python中执行ssh host 'echo test' | cat
,我已尝试
import paramiko
import subprocess
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='user')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test')
proc = subprocess.Popen(['cat'], stdin=ssh_stdout)
outs, errs = proc.communicate()
print(outs)
但我得到例外'ChannelFile' object has no attribute 'fileno'
。似乎Paramiko的ssh_stdout
不能用作subprocess.Popen的stdin。
答案 0 :(得分:1)
是的,subprocess
无法重定向"假冒"文件。它需要fileno
,它只用" real"定义。文件(io.BytesIO()
也没有)。
我会手动完成,如下面的代码所示:
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
proc.stdin.write(ssh_stdout.read())
proc.stdin.close()
所以你告诉Popen
输入是一个管道,然后你在管道中写入ssh输出数据(并关闭它以便cat
知道什么时候必须结束)
答案 1 :(得分:1)
根据文档,define i32 @test2() {
entry:
%calltmp = call i32 @UInt()
%datasize = alloca i32
switch i32 %calltmp, label %sw.bb.0 [
i32 1, label %sw.bb.1
i32 2, label %sw.bb.2
i32 3, label %sw.bb.3
]
; %res = alloca i8 ===> deleted
;store i8 0, i8* %res ===> deleted
;%datasize1 = load i32, i32* %datasize ===> deleted
ret i32 %datasize1 ===> UNABLE to delete
sw.bb.0: ; preds = %entry
%resclone0 = alloca i10
store i10 0, i10* %resclone0
%datasize1clone0 = load i32, i32* %datasize
对象不会直接包装实际的文件描述符(因为在SSH中发生解密和解复用等),所以它不能直接用作ChannelFile
的文件描述符。
像
这样的东西Popen
可能有用;即,您手动读取SSH标准输出流,一次最多4096个字节,并将它们写入子进程的标准输入管道。 我不确定远程命令退出时上面的代码如何表现,所以YMMV。