我有以下 Bash 脚本:
#!/usr/bin/expect -f
set port [lindex $argv 0]
set cmd_target [lindex $argv 1]
set login [lindex $argv 2]@[lindex $argv 3]
set username [lindex $argv 2]
set hostname [lindex $argv 3]
set password [lindex $argv 4]
spawn ssh -X -p $port $login $cmd_target
expect {
{Are you sure you want to continue connecting (yes/no/\[fingerprint\])?}
{
exp_send "yes\r"
exp_continue
}
{password:} {send "$password\r"}
}
expect eof
如果我按如下方式使用它,它会起作用:
$ port_0=22
$ username_0=somename
$ hostname_0=192.168.70.92
$ password_0=...
$ cmd_target="pwd"
$ ./my_script $port_0 $cmd_target $username_0 $hostname_0 $password_0
输出为:
spawn ssh -X -p 22 [email protected] pwd
[email protected]'s password:
/home/somename
但是如果我使用cmd_target="ls -la"
,脚本就会被抛出:
spawn ssh -X -p 22 -la@somename ls
ssh: Could not resolve hostname ls: Temporary failure in name resolution
expect: spawn id exp4 not open
while executing
"expect eof"
为什么会发生这种情况?我怎样才能让它按预期工作?令人沮丧的是,这工作得很好:
ssh $username_0@$hostname_0 ls -la
答案1
这不是一个 Bash 脚本,而是一个仅从 Bash 调用的 Tcl/Expect 脚本。
为什么会发生这种情况?
在 Bash 中,$
除非引用,否则所有扩展都会受到分词的影响,因此您的脚本会收到[lindex $argv 1] => "ls"
和[lindex $argv 2] => "-la"
。
我怎样才能让它按预期工作?
从 Bash 运行脚本时,请确保在变量周围使用双引号,就像指定带有空格的文字参数时一样:
./my_script $port_0 "$cmd_target" $username_0 $hostname_0 "$password_0"
未加引号的扩展也受通配符(glob)处理的影响,因此您也需要在周围加上引号"$password"
(以防它包含*
或诸如此类的东西)——并且一般来说,在任何扩展周围都要加上引号。
这不适用于您的 Expect 脚本;spawn ssh ... $cmd_target
在 Tcl 中可以。