使用 Expect 脚本的 Bash 会出现 ssh 调用错误

问题描述 投票:0回答:1

在 bash 脚本中,我有一个 except 段,它通过 ssh 将命令发送到机器。我有

bash -c
,因为我需要在此命令中设置环境变量。 但我收到错误:

extra characters after close-quote
    while executing
"spawn -noecho ssh -t anon@machine  'bash -c "cd /tmp;"'
"

当我手动运行该命令时

ssh -t anon@machine  'bash -c "cd /tmp;"'
它工作正常。这里出了什么问题?

   ssh_param="-t ${scp_user}${_machine}  'bash -c \"cd /tmp;\"'"

    /usr/bin/expect <<-EOF1
    set timeout 360
    spawn -noecho ssh ${ssh_param}
    expect {
        "password:" { 
             send "${_pass}\r" 
         }
         eof { exit }
    }
    expect {
         eof { exit }
    }
EOF1

另外,如果我将 ssh_param 设置为

ssh_param="-t ${scp_user}${_machine}  \"cd /tmp;\""
这有效,那么为什么
bash -c ... 
会导致它失败?

bash shell ssh expect
1个回答
0
投票

bash 在定界文档上进行参数替换后,

expect
运行于

set timeout 360
spawn -noecho ssh -t XXXYYY 'bash -c "cd /tmp;"'
expect {
    "password:" { 
         send "ZZZ\r" 
     }
     eof { exit }
}
expect {
     eof { exit }
}

expect
脚本是用
tcl
语言编写的,其基本工作原理是将一行分成单词,并将第一个单词视为命令,在进行替换后将其余单词作为参数运行。有点像 shell 那样,但有更合理的规则。用于解析 tcl 的 12 条规则 称为 Dodekalogue。

单引号不用于将多个单词组合成一个 - 仅使用双引号、

[]
(表示要评估的命令和参数)和
{}
(不替换或评估其中的任何内容)。所以这条线

spawn -noecho ssh -t XXXYYY 'bash -c "cd /tmp;"'

分为

spawn
-noecho
ssh
-t
XXXYYY
'bash
-c
"cd /tmp;"'
。最后一个单词的右双引号后面的单引号是错误的。通常在 tcl 中,您只需将其括在大括号中(或双引号,但随后您必须转义嵌套的引号):

spawn -noecho ssh -t XXXYYY {bash -c "cd /tmp;"}

这意味着您设置的 shell 变量需要类似于

ssh_param="-t ${scp_user}${_machine} {bash -c \"cd /tmp;\"}"

在 tcl/expect 中编写整个内容,而不是构建期望脚本执行的 shell 将使生活更轻松,因为您不必在不同的引用样式之间切换,担心 shell 参数扩展导致生成无效的 tcl,如本例所示等等

© www.soinside.com 2019 - 2024. All rights reserved.