我有以下脚本来抓取交换机的 arp 表。无论我如何尝试转义所有内容、引用它或以其他方式尝试,我都无法使其正常工作。bash 行在传递到 Expect 解释器之前由我自己的 shell 解释。我希望 bash 行按原样传递到交换机并在那里执行,但我需要以某种方式在某个时候扩展 $thirdoctet 变量,并且我希望扩展 ssh@{ip}。
Arista 的 bash 似乎不喜欢设置变量。我无法在其中定义 thirdoctet=3。
function get-arp {
echo ${ip}
/usr/bin/expect > arista-arp-dump-${ip} << EOF
spawn ssh admin@${ip}
expect "assword: "
send "password\r"
expect "localhost>"
send "bash for i in `seq 1 5`; do ping -c 1 10.$thirdoctet.1.$i; done"
expect "localhost>"
send "bash for i in `seq 10 19`; do ping -c 1 10.$thirdoctet.1.$i; done"
expect "localhost>"
send "show ip arp\r"
expect "localhost>"
send "exit\r"
expect "eof"
EOF
tail -n +2 arista-arp-dump-${ip} | grep b8ae | awk '{print $1,$3}' | tr ' ' ',' > arista-arp.csv
sed 's/\(.*\)\./\1 /' arista-arp.csv > tmp && mv tmp arista-arp.csv
sed 's/\(.*\)\./\1 /' arista-arp.csv > tmp && mv tmp arista-arp.csv
sed '/^$/d;s/[[:blank:]]//g' arista-arp.csv > tmp && mv tmp arista-arp.csv
rm arista-arp-dump-${ip}
}
get-arp
答案1
问题是,您有变量,您希望在不同时间(甚至在不同的服务器上)替换它们,但是您已对脚本进行了编码,以便在 bash 函数运行时,它们都替换一次。 bash here-doc 的作用类似于双引号字符串,因此在 heredoc 文本移交给 expect 命令之前,所有变量$ip
、$thirdoctet
和$i
都已替换。 似乎您希望$ip
和$thirdoctet
被扩展,但不是$i
。 您需要更聪明地使用引号。
我会这样做:
- 将 heredoc 单引号括起来,这样 shell 就不会替换任何变量
- 导出
$ip
和$thirdoctet
变量以便期望可以访问它们。 - 转义
$i
变量,以便仅由远程计算机上的 bash 替换 - 你忘记按“回车”键了——
\r
在几个发送命令中都遗漏了
function get-arp {
export ip
export thirdoctet
# note the quotes: ........................v...v
/usr/bin/expect > arista-arp-dump-${ip} << 'EOF'
# use the 'ip' variable from the environment
spawn ssh admin@$env(ip)
expect "assword: "
send "password\r"
expect "localhost>"
# use the 'thirdoctet' variable from the environment and escape `\$i`
send "bash for i in `seq 1 5`; do ping -c 1 10.$env(thirdoctet).1.\$i; done\r"
expect "localhost>"
send "bash for i in `seq 10 19`; do ping -c 1 10.$env(thirdoctet).1.\$i; done\r"
expect "localhost>"
send "show ip arp\r"
expect "localhost>"
send "exit\r"
expect "eof"
EOF
...