1 使用expect命令
[root@localhost /tmp/sdl/test]#expect ssh.exp 192.168.37.128
spawn ssh root@192.168.37.128 ls /home/
root@192.168.37.128's password:
guest
sdl
[root@localhost /tmp/sdl/test]#cat ssh.exp
#!/usr/bin/expect
set timeout 30
set ip [lindex $argv 0]
set username root
set password 111111
spawn ssh $username@$ip "ls /home/"
expect {
"(yes/no)" {send "yes\r"; exp_continue}
"password:" {send "$password\r"}
}
interact
2 配置免密登录
若用户没有ssh key则先通过执行ssh-keygen生成ssh key
将本地的id_rsa.pub追加到远程主机的authorized_keys文件集中
scp id_rsa.pub 192.168.37.128:~/.ssh/tmp #注意不要覆盖远程机器的id_rsa.pub
ssh 192.168.37.128 -t “cd ~/.ssh/;cat tmp >> authorized_keys;rm -rf tmp”
验证登录
ssh 192.168.37.128
3 scp和ssh通用的expect交互脚本
#!/usr/bin/expect
set command_1 [lindex $argv 0]
set command_2 [lindex $argv 1]
set command_3 [lindex $argv 2]
set check_key [lindex $argv 3]
set passwords [lindex $argv 4]
set timeout 30
if { $command_1 == "ssh" } {
spawn ssh $command_2 $command_3
expect {
"(yes/no)" {send "yes\r";exp_continue}
"assword" {send "$passwords\n";exp_continue}
"$check_key" {send ""}
}
} else {
spawn bash -c "scp -o StripHostKeyChecking=no $command_2 $command_3"
expect {
"(yes/no)" {send "yes\r";exp_continue}
"assword" {send "$passwords\n";exp_continue}
"$check_key" {send ""}
}
}
expect eof
catch wait result
exit [lindex $result 3]
interact
执行演示:
[root@localhost /home/Sudley]#./exp "ssh" "root@192.168.37.13" "ls /home/Sudley" "." "111111"
spawn ssh root@192.168.37.13 ls /home/Sudley
ssh: connect to host 192.168.37.13 port 22: No route to host
[root@localhost /home/Sudley]#echo $?
255
[root@localhost /home/Sudley]#./exp "ssh" "root@192.168.37.132" "ls /home/Sudley|head" "123.in" "111111"
spawn ssh root@192.168.37.132 ls /home/Sudley|head
root@192.168.37.132's password:
123_1.txt
123.in
123.out
123.txt
a.out
array
array.c
array.h
array.o
exp
[root@localhost /home/Sudley]#echo $?
0
[root@localhost /home/Sudley]#
参数说明:
command_1 - command_3是ssh或者scp命令的组成部分
set check_key [lindex $argv 3]是检查命令是否执行成功的参数,用于ssh或者scp命令不需要输入password的场景(当不确定是否需要输入password时很有用)
if { $command_1 == “ssh” } {最后的"} {“中间需要空格隔开,要不可能会报错"extra characters after close-brace”
catch wait result
exit [lindex $result 3]
expect脚本执行退出后退出状态码为ssh/scp命令的退出状态码
注意到scp前面有个bash -c,这是是scp命令支持通配符*
如果不带bash -c,则scp命令$command_2 $command_3部分的*就是*