这段代码在没有命令行参数的情况下工作正常,但是当我将IP作为参数传递给脚本时,登录linux框后停止
bash -x -o igncr Master.sh 10.104.24.196
我不知道发生了什么,任何帮助将不胜感激。
if [ "$#" -eq 0 ]; then
IP="10.104.24.196"
else
IP="$1"
fi
PWD="something"
echo "Connecting to $IP with password:$PWD"
> ~/.ssh/known_hosts
/usr/bin/expect -<< EOD
set timeout -1
spawn ssh "$IP" -l root
expect "(yes/no)?"
send "yesn"
expect "password"
send "$PWDn"
expect "$*" <- stops here
send "cd somewheren"
send "./db_deploy.shn"
expect "Script execution completed."
send "cd somewheren"
send "./apps_deploy.shn"
expect "Script execution completed."
send "exitn"
expect eof
EOD
#dosomething else
问题是因为expect "$*"
.
匹配文字美元符号 ( $
(,那么在双引号内使用时应使用以下方式。
expect {\$}
由于$
符号对tcl
和expect
都是特殊的,为了匹配字面上的美元符号,我们需要用反斜杠转义它两次,当然还需要一个反斜杠来转义反斜杠本身。
还有 2 个可以完成的增强功能如下:
要通过expect
发送"输入/返回"密钥,建议使用r
,而不是n
。 (虽然在你的问题中没什么大不了的。 :)(
在生成 ssh 会话之前,您正在覆盖known_hosts
文件(> ~/.ssh/known_hosts
(,因此您期望"(是/否("仅在主机刚进入系统时才发生。
spawn ssh "$IP" -l root
expect "(yes/no)?
在 exp_continue
的帮助下,我们可以在不覆盖known_hosts的情况下处理相同的问题。(但是,如果每次删除已知主机是你的真实意图,你不需要添加这部分(
通过在脚本中组合这些更改,它将如下所示:
#!/bin/bash
if [ "$#" -eq 0 ]; then
IP="10.104.24.196"
else
IP="$1"
fi
PWD="something"
echo "Connecting to $IP with password:$PWD"
# I have commented this line, since I am using exp_continue.
# If you don't want, then keep your code as such
#> ~/.ssh/known_hosts
/usr/bin/expect -<< EOD
set timeout 60; # 1 min of timeout
spawn ssh "$IP" -l root
expect {
# you can keep your old code here if you want.
"(yes/no)" {send "yesr";exp_continue}
"password"
}
send "$PWDr"
expect {\$}
send "cd somewherer"
send "./db_deploy.shr"
expect "Script execution completed."
send "cd somewherer"
send "./apps_deploy.shr"
expect "Script execution completed."
send "exitr"
expect eof
EOD
与其将期望脚本直接嵌入到 bash 脚本中,不如单独保留文件并调用 expect 脚本,如下所示,
expect -c yourscript.exp
查看此处以了解在 bash 脚本中嵌入 expect 脚本时双引号和单引号的用法。
更新:我错过timeout
值是多么可怜。
expect
的默认超时值为 10 秒。这可以通过设置新值来更改。
set timeout 60; # This value is in terms of seconds.
通过将超时设置为 -1,我们使其无限等待。 您已使用该值。尝试将其更改为其他值(例如 60,即 1 分钟(。
也许,在您的情况下,如果$
没有得到匹配,它将如此进行。如果要正常处理timeout
,则应使用以下方法。
expect {
{\$} {puts "matched dollar sign"}
timeout { puts "timeout happened"}
}
这仍然不能准确回答您的问题。您可以尝试带有-d
标志的expect
并在您的问题中分享输出吗?以便我们为您提供帮助。