如果目录存在,则期望脚本失败

Expect script fails if directory exists

我的 expect 脚本允许我使用我的 ssh 密钥登录服务器,但如果它尝试创建的目录已经存在,它就会失败。

当我尝试在目标服务器上创建目录时,整个脚本失败并出现此错误:

    authorized_keys                                                                                                             100%  408   478.0KB/s   00:00
send: spawn id exp8 not open
    while executing
"send "$password\r""
    (procedure "check_host" line 5)
    invoked from within
"check_host $line"
    ("while" body line 2)
    invoked from within
"while {[gets $fp line] != -1} {
    check_host $line
}"
    (file "./transfer_keys.sh" line 29)

这是我的脚本:

#!/usr/bin/expect

set timeout 20
set user my_user_name
set password my_pass
set auth_keys /home/my_user_name/.ssh/authorized_keys
set ssh_dir /home/my_user_name/.ssh

proc check_host {hostname} {
    global user password auth_keys ssh_dir
    spawn scp $auth_keys $user@$hostname:
    expect "password"
    send "$password\r"
    spawn ssh $user@$hostname
    expect "password"
    send "$password\r"
    expect "$ "                ;# adjust to suit the prompt accordingly
    send "mkdir $ssh_dir\r"
    send "chmod 700 .ssh\r"
    send "mv authorized_keys $ssh_dir\r"
    send "chmod 600 $ssh_dir/authorized_keys\r"
    send "exit\r"
    expect eof

}


set fp [open host.txt r]
while {[gets $fp line] != -1} {
    check_host $line
}
close $fp

如果我删除目标服务器上的 ~/.ssh 目录并再次 运行 它 运行 没问题!

如果 ~/.ssh 目录不存在,我如何只在目标服务器上创建它?

如果您已经复制了授权密钥,scp 将不会要求输入密码,因此 expect "password" 将在 20 秒后超时。完成以下 send "$password\r" 后,scp 将完成并且连接关闭,因此会出现错误。

通常,expect 不仅用于匹配模式,而且如果匹配则还指定命令到 运行。只需以这种方式组合 expect 和 send:

expect "password" { send "$password\r" }

那么只有看到提示才会发送。您还应该为此 scp 命令添加一个 expect eof,以清理连接。

Per @glennjackman,您可能会受益于使用 ssh-copy-id 将 public 密钥复制到另一台服务器。


您可以使用以下shell命令列表来确定您是否需要使用密码登录:

ssh -o BatchMode=yes $host : || echo "host $host requires password login"