我有一个 bash+expect 脚本,它必须通过 ssh 连接到远程计算机,读取那里的文件,找到带有“主机名”的特定行(如“主机名 aaaa1111”),并将此主机名存储到变量中,以供稍后使用。我如何获取“主机名”参数的值?我以为该行内容将在 $expect_out(buffer) 变量中(这样我就可以扫描并分析它),但事实并非如此。我的脚本是:
#!/bin/bash
----bash part----
/usr/bin/expect << ENDOFEXPECT
spawn bash -c "ssh root@$IP"
expect "password:"
send "xxxx\r"
expect ":~#"
send "cat /etc/rc.d/rc.local |grep hostname \n"
expect ":~#"
set line $expect_out(buffer)
puts "line = $line, expect_out(buffer) = $expect_out(buffer)"
...more script...
ENDOFEXPECT
这里http://en.wikipedia.org/wiki/Expect有一个例子:
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
在这种情况下似乎不起作用,或者脚本有什么问题?
答案1
首先,您的 heredoc 就像一个双引号字符串,因此$expect_out
变量在启动之前会被 shell 替换expect
。您需要确保您的 heredoc 不会被 shell 触碰。因此,任何 shell 变量都需要以不同的方式获取。在这里,我假设IP
是一个 shell 变量,并且我正在通过环境传递它。
export IP
/usr/bin/expect << 'ENDOFEXPECT'
set prompt ":~#"
spawn ssh root@$env(IP)
expect "password:"
send "xxxx\r"
expect $prompt
send "grep hostname /etc/rc.d/rc.local \n"
expect $prompt
set line $expect_out(buffer)
...more script...
ENDOFEXPECT
答案2
为什么要用 expect 来实现这一点?
ssh -i ssh_private_key root@${IP} "grep -E -o 'hostname.*$' /etc/rc.d/rc.local"