在 ssh 连接中使用 expect 时出现 awk weird parse '~' parse error

awk weird parse '~' parse error while using expect in a ssh connection

我正在尝试根据机器的内存使用情况自动建立符号链接,为此我想首先检查我的主目录下哪个目录使用的内存最多,为此我正在使用这个命令

cd /directory && du -h 2>/dev/null | awk '{ if ( ~ /G/) {print [=12=]}}' | grep './' | awk -F '.' '{print }' 这在 ssh 连接上完美运行,但是当我尝试将它放在 expect 下的脚本中时,我收到错误:

{ if ( ~ /G/) {print myscriptname}}
       ^ parse error
{ if ( ~ /G/) {print myscriptname}}
            ^ parse error

我觉得最奇怪的是,命令以某种方式试图使用我的实际脚本的文件名作为参数,即使我是 运行 通过 ssh 连接的命令。

我的完整代码是

#!/bin/bash
expect <<-EOF
set timeout 5
spawn ssh -oPort=22 user@ip
expect "*password" { send "password\r" }
expect "*#" { send "cd /directory && du  -h 2>/dev/null | awk '{ if ( ~ /G/)  {print [=11=]}}' | grep './' | awk -F '.' '{print }'\r" }
expect "*#" { send "exit\r" }
EOF

这是由于 send 的 double-quoted 参数——Tcl 将扩展 double-quoted 字符串中的任何 $variables

您可能想要更改

expect "*#" { send "cd /directory && du  -h 2>/dev/null | awk '{ if ( ~ /G/)  {print [=10=]}}' | grep './' | awk -F '.' '{print }'\r" }

对此,使用大括号防止变量膨胀

expect "*#" { 
    send {cd /directory && du  -h 2>/dev/null | awk ' ~ /G/ && /.\// {print [=11=]}' | awk -F '.' '{print }'}
    send "\r"
}

啊,是的,我看到了主要问题:您的期望代码在 shell heredoc 中,并且会受到变量扩展的影响。这甚至发生在 expect 启动之前。

这里的秘诀是告诉 shell 到 single-quote 整个文档:

expect << 'EOF'
...
EOF

现在,</code> 和 <code>[=16=] 将留给 awk 使用。