在bash脚本中期望:expect_out不打印缓冲区

时间:2011-04-08 01:47:18

标签: bash expect

我试图通过登录交换机捕获“dir”命令的输出,但我无法这样做。我在bash中使用expect。我正在利用expect_out来捕获缓冲区中该命令的输出并将其打印出来。实际上我想捕获输出并对其执行一些操作 SCript:

#!/bin/bash  
expect -c "  
spawn telnet 1.1.1.1 2000  
sleep 1  
send \"\r\"  
send \"\r\"  
expect {  
Prompt> { send \"dir\r\"  }  
}  
set output $expect_out(buffer)  
"    
echo "$output"  

输出:

spawn telnet 1.1.1.1 2000  
Trying 1.1.1.1...  
Connected to 1.1.1.1 (1.1.1.1).  
Escape character is '^]'.  




Prompt>  

Prompt>  

显示这些提示后,脚本将退出。请帮助。

编辑:

我现在将其拆分,以便我可以使用参数替换以及单引号。现在我面临着不同的错误。

脚本:

expect -c "
spawn telnet $IP $PORT1
sleep 1
send \"\r\"
send \"\r\"
"
expect -c '
expect {
Prompt> { send \"dir\r\" }
set output $expect_out(buffer)
puts "$output"
}
'

输出:

spawn telnet 172.23.149.139 2033
can't read "expect_out(buffer)": no such variable
while executing
"expect {
Prompt> { send \"dir\r\" }
set output $expect_out(buffer)
puts "$output"
}
"

编辑2: 你好Chris / all,

我根据你的建议改了它。但我仍面临错误。

脚本:

output=$(expect -c '  
spawn telnet '"$IP $PORT1"'  
sleep 1  
send '"\r"'  
send '"\r"'  

expect Prompt> { send '"dir\r"'  }  
expect '"\n"'  
expect -indices Prompt>  
puts '"[string range $expect_out(buffer) 0 [expr $expect_out(0,end) - 1]]"'  

')  

echo "======="  
echo "$output"  
echo "======="  

输出:

syntax error in expression "(0,end) - 1"  
    while executing  
"expr (0,end) - 1"  
    invoked from within  
"string range (buffer) 0 [expr (0,end) - 1]"  
    invoked from within    
"puts [string range (buffer) 0 [expr (0,end) - 1]]"  

=======
spawn telnet 1.1.1.1 2000
Trying 1.1.1.1...
Connected to 1.1.1.1 (1.1.1.1).
Escape character is '^]'.




Prompt>

Prompt>

=======

因此,为了避免错误,我改变了行

puts '"[string range $expect_out(buffer) 0 [expr $expect_out(0,end) - 1]]"'

puts '"$expect_out(buffer)"'

但是后来我没有收到任何错误,但是dir的输出也没有被打印出来。类似的东西:

Prompt>

Prompt> (buffer)

2 个答案:

答案 0 :(得分:3)

第二个“拆分”Expect程序无法访问衍生的 telnet 进程。当你像那样拆分它们时,你使它们独立(一个不能访问变量或另一个的状态;实际上当第二个启动第一个变量或它的 telnet 过程时,没有更长时间存在。)


shell将自动连接任何字符串(未被未引用/未转义的空格分隔),而不考虑它们使用的引号(如果有)。这意味着您可以开始将Expect程序的第一部分放在单引号中,切换到参数替换的双引号,然后返回到程序其余部分的单引号(以避免必须转义任何{{1在你的期望代码中出现。)

"$\`

它使用单引号来保护大部分程序,但切换回双引号,让shell将其HOST和IP参数替换为Expect程序的文本。


接下来,启动 expect 的shell无法访问Expect程序中的变量集。从子进程收集输出的常规方法是让它写入stdout或stderr并让shell通过命令替换(expect -c ' spawn telnet '"$HOST $PORT"' sleep 1 ⋮ (rest of Expect program) ' )收集输出。

在Tcl(和Expect)中,您可以使用$()将字符串发送到stdout。但是,默认情况下,Expect还会向stdout发送正常的“交互”输出(从任何生成的命令接收的内容以及它发送给它们的内容;即,如果您手动运行生成的命令,您会看到什么)。您可以使用puts禁用此默认日志记录。

你可以写这样的程序:

log_user 0

答案 1 :(得分:0)

因为您的expect脚本用双引号括起来,所以shell正在将$expect_out扩展为空字符串。将expect脚本的主体放在单引号中。

当你在expect中设置变量时,shell将不知道。当expect脚本完成时,它的变量也会消失。您必须puts expect_out缓冲区。