2016-10-21 114 views
0

我试图使用expect作为更大的python程序的一部分来自动执行任务,并且在远程机器上运行ssh命令的stdout时遇到了很多麻烦。我之前没有使用过expect,也没有成功在手册页上找到解决方案。使用期望从ssh获得输出

我需要使用expect在实际能够运行此命令之前自动执行一些交互操作,但为了简化问题,我在此删除了它们。

这里是节目的一个简化的例子:

import subprocess 

expect = """ 
/usr/bin/expect <<EOF 

spawn ssh some_machine ls 
expect eof 
puts "$expect_out(buffer)" 
""" 

output = subprocess.check_output(expect, shell=True) 
print(output) 

输出:

b'spawn ssh some_machine ls\r\n116029\r\nArchive\r\n\r\n(buffer)\n' 

它似乎含有产卵命令以及“(缓冲器)”结尾。我不确定为什么会发生这种情况。我试图只得到ls的结果。

如果我打开调试模式的预期,我看到expect_out(buffer)被设置为我想要返回,但puts不反映这一点。

输出:

expect version 5.45 
argv[0] = /usr/bin/expect argv[1] = -d 
set argc 0 
set argv0 "/usr/bin/expect" 
set argv "" 
executing commands from command file 
parent: waiting for sync byte 
parent: telling child to go ahead 
parent: now unsynchronized from child 
spawn: returns {1753} 
expect: read eof 
expect: set expect_out(spawn_id) "exp7" 
expect: set expect_out(buffer) "116029\r\nArchive\r\n" 
<wrong output as above> 
+1

?你只是运行一个命令并阅读它的标准输出。你可以运行'subprocess.check_output('ssh some_machine ls',shell = True)'。 – larsks

+0

为简单起见,我简化了脚本,但我需要使用它来自动化一些交互,然后才能收集输出。 – Matteo

+0

另外,你的shell脚本'expect'缺少一个终端'EOF'来匹配'<< EOF'。 – larsks

回答

1

你可以期望从与log_user命令禁止日志输出:

log_user 0 
spawn ssh some_host ls 
expect eof 
puts "$expect_out(buffer)" 

没有log_user 0,我得到:

$ expect -f sample.tcl 
spawn ssh some_host ls 
file1 
file2 

通过添加log_user 0,我得到:

$ expect -f sample.tcl 
file1 
file2 

似乎有些奇怪,当你喂通过stdin expect脚本,但以下似乎工作:你为什么要使用`expect`这里

import subprocess 
import tempfile 

expect = """ 
log_user 0 
spawn ssh some_host ls < /dev/null 
expect eof 
puts "$expect_out(buffer)" 
""" 

with tempfile.NamedTemporaryFile() as fd: 
    fd.write(expect) 
    fd.flush() 
    fd.seek(0) 
    output = subprocess.check_output(['expect', fd.name]) 

print(output) 
+0

我得到的唯一结果是:'b'(buffer)\ n'' – Matteo

+0

您的评论中缺少某些内容,但我想我会看到您想要描述的行为。看看... – larsks

+0

是的,它使用sample.tcl工作。但是,当我在Python中使用时,它不能正常工作,输出似乎只在上面。我会继续调查... – Matteo