如果目录存在,则期望脚本失败
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"
我的 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"