heredoc 语法中的变量扩展和转义

heredoc 语法中的变量扩展和转义

我有以下脚本来抓取交换机的 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。 您需要更聪明地使用引号。

我会这样做:

  1. 将 heredoc 单引号括起来,这样 shell 就不会替换任何变量
  2. 导出$ip$thirdoctet变量以便期望可以访问它们。
  3. 转义$i变量,以便仅由远程计算机上的 bash 替换
  4. 你忘记按“回车”键了——\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
    ...

相关内容