如何修复被 ssh 选项引发的 Bash 脚本?

如何修复被 ssh 选项引发的 Bash 脚本?

我有以下 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 中可以。

相关内容