上周工作中,遇见一些重复性的工作,为了方便,于是写起了脚本。
在这个脚本中,需要通过 s s h ssh ssh 链接到远程服务器,然后执行特定的操作,但是链接服务器的时候, s s h ssh ssh 需要验证是否信任机器(第一次链接的话需要输入 y e s yes yes)以及密码,如果每次都要自己手动去操作,就失去了脚本的意义。此时, e x p e c t expect expect 脚本就派上了用场。
首先安装 e x p e c t expect expect,因为默认是没有安装这个的, U b u n t u Ubuntu Ubuntu 系统可以直接通过 s u d o a p t − g e t i n s t a l l e x p e c t sudo\ apt-get\ install\ expect sudo apt−get install expect 来安装,然后写好 e x p e c t expect expect 脚本,假如说叫做 l o g i n − v i a − s s h login-via-ssh login−via−ssh,如果脚本没有参数的话,直接 e x p e c t l o g i n − v i a − s s h expect\ login-via-ssh expect login−via−ssh 就可以了,注意必须用 e x p e c t expect expect 来运行这个脚本,其他 s h e l l shell shell 工具是无法解析这个脚本的。
不过我这里写的 l o g i n − v i a − s s h login-via-ssh login−via−ssh 脚本有一些参数:
Usage: expect login-via-ssh username password hostname realip script
主要功能是通过 s s h ssh ssh 链接到用户名为 u s e r n a m e username username,密码为 p a s s w o r d password password 的服务器,服务器的主机名叫做 h o s t n a m e hostname hostname,真实的 I P IP IP 地址为 r e a l i p realip realip,链接到这个服务器后执行 s c r i p t script script 脚本。
#!/usr/bin/expect -f
set timeout 10
set username [lindex $argv 0]
set password [lindex $argv 1]
set hostname [lindex $argv 2]
set realip [lindex $argv 3]
set script [lindex $argv 4]
spawn ssh -l $username $realip "echo '$password' | sudo -S ~/$script $hostname"
expect {
"(yes/no)?" {
send "yes\n"
expect "password:"
send "$password\n"
}
"password:" {
send "$password\n"
}
}
interact
这里用来实现自动输入的是 e x p e c t expect expect 部分,当检测到 ( y e s / n o ) ? (yes/no)? (yes/no)? 的时候,会自动输入 y e s yes yes,检测到 p a s s w o r d : password: password: 时会自动输入 p a s s w o r d password password。
另外, s p a w n spawn spawn 后双引号里的内容,是要在 s s h ssh ssh 远程链接到的服务器上执行的,因为 s u d o sudo sudo 权限需要键入密码,所以通过 e c h o echo echo 的方式来进行自动输入密码。
说到这里,就不得不说的是,常见的自动输入密码的方法有三种,但是对于 s s h ssh ssh 和 s c p scp scp 这种命令只能通过 e x p e c t expect expect 来进行自动输入密码的操作。
x s c p xscp xscp 脚本:
#!/usr/bin/expect -f
# Usage: expect xscp a b c
set timeout 10
set source [lindex $argv 0]
set target [lindex $argv 1]
set passwd [lindex $argv 2]
spawn scp $source $target
expect {
"(yes/no)?" {
send "yes\n"
expect "password:"
send "$passwd\n"
}
"password:" {
send "$passwd\n"
}
}
interact
更多有趣的脚本欢迎大佬们指点。