我试图通过登录交换机捕获“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)
答案 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缓冲区。