Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 为什么我的Expect脚本只响应未运行的命令?_Bash_Shell_Ssh_Automation_Expect - Fatal编程技术网

Bash 为什么我的Expect脚本只响应未运行的命令?

Bash 为什么我的Expect脚本只响应未运行的命令?,bash,shell,ssh,automation,expect,Bash,Shell,Ssh,Automation,Expect,我正在尝试自动化一些ssh过程。我有我的期望代码。但是我的Expect代码只回显/打印命令。它实际上并不运行该命令 #!/usr/bin/expect -f set timeout 10 set usrnm "aaaaaa" set pwd "pppppp" set addr1 "xxx.cloud.xxx.com -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" set addr2 "xxx.xxxx.xxxx.com"

我正在尝试自动化一些
ssh
过程。我有我的期望代码。但是我的Expect代码只回显/打印命令。它实际上并不运行该命令

#!/usr/bin/expect -f

set timeout 10
set usrnm "aaaaaa"
set pwd "pppppp"
set addr1 "xxx.cloud.xxx.com -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
set addr2 "xxx.xxxx.xxxx.com"

spawn ssh $usrnm@$addr1

expect {

    "(yes/no)?" {send "yes\r";exp_continue}

    "password: " {send  "$pwd\r"}

}


expect "*#"
send "ssh $usrnm@$addr2\r"

expect {

    "(yes/no)?" {send "yes\r";exp_continue}

    "password:" {send  "$pwd\r"}

}

expect "*#"

send "cd /tmp/myself/folder\r"

expect "*#"

send "./run_engine.sh test.py\r"

expect eof

#interact
所以如果我这样做了

expect my_expect.exp
它只打印命令:

spawn-sshaaaaaa@xxx.cloud.xxx.com-o UserKnownHostsFile=/dev/null-o StrictHostKeyChecking=no
(10秒后)
sshaaaaa@xxx.xxxx.xxxx.com
(10秒后)
cd/tmp/amz337/COAFALV
(10秒后)
./run_engine.sh test.py
(出口)

我的脚本出了什么问题?

因为当变量被替换时,Tcl(因此Expect)不会改变单词边界。您正在尝试登录名为的主机:

xxx.cloud.xxx.com -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
空间和所有

从逻辑上讲,将
ssh
选项放入保存地址的变量是没有意义的。我可以建议:

set addr1 "xxx.cloud.xxx.com"
set addr2 "xxx.xxxx.xxxx.com"
set ssh_opts($addr1) {-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no}
set ssh_opts($addr2) {}
然后

{*}
语法是Tcl的“splat”操作符,它将带有空格的单词拆分为单个单词。见规则5

稍后,当您连接到第二台机器时,您将插入到字符串中,因此不需要splat:

send "ssh $ssh_opts($addr2) $usrnm@$addr2\r"
您可能希望捕获超时事件并中止脚本:

expect {
    timeout      {error "timed-out connecting to $addr1"}
    "(yes/no)?"  {send "yes\r"; exp_continue}
    "password: " {send  "$pwd\r"}
}
在脚本结束时,在运行引擎脚本完成后,您仍然连接到addr2,因此
expect eof
实际上不会在生成的进程上检测到eof。您将在10秒后超时,Expect进程将退出。为了保持整洁,您应该:

send "./run_engine.sh test.py\r"
expect "*#"
send "exit\r"
# This prompt is from addr1
expect "*#"
send "exit\r"
# _Now_ the spawned ssh process will end
expect eof
如果您认为run_引擎脚本将花费10秒以上的时间,则应在发送该命令之前调整timeout变量

此外,在开发Expect脚本时,应启用调试:

exp_internal 1

这将向您展示幕后的情况,特别是在查看模式是否匹配时。

一些切题建议:使用SSH密钥身份验证将a)更安全,b)允许您使用纯shell脚本而不是
expect
,c)因此更易于维护。
exp_internal 1