linux 里面很多命令都是需要人为交互的,对于做成脚本来说,有点不合适了,比如通过密码连接 SSH 必须要在控制台输入密码(安全起见还是用 rsa key),expect
是预期的意思,它可以实现我们预期的结果。
安装
1 2 3 4 5
| sudo apt install -y expect
sudo yum install -y ecpect
|
解释器使用 expect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #!/usr/bin/expect
set IP [lindex $argv 0] set PASSWD [lindex $argv 1] set CMD [lindex $argv 2]
spawn ssh $IP $CMD expect { "(yes/no)?" { send "yes\r"; exp_continue }
"password:" { send "$PASSWD\r" } "*host " { exit 1 } } expect eof
|
这种方式由于解释器使用了 expect,所以只能使用有限的命令,不是很推荐
执行结果赋予变量
1 2 3 4
| #!/usr/bin/expect
set result [exec hostname -I] puts "本机IP地址是: $result"
|
解释器使用 bash
假设 certbot 不支持非交互使用
1 2 3 4 5 6 7 8 9
| #!/bin/bash export LC_CTYPE="en_US.UTF-8" expect -c ' set timeout 3 spawn ssh user@<host> -p 60022 expect "password" send "password\r" interact '
|
直接使用 expect 命令
这种和切换解释器类似, 类比于 ./test.sh
和 bash test.sh
的关系。
vim test.sh
1 2 3 4 5
| spawn ldapadd -x -D cn=Manager,dc=i,dc=com -W -f /vagrant/basedomain.ldif expect { "Enter LDAP Password:" {send "123456\n";exp_continue} eof }
|
一些例子🌰
自动登录带两步验证码的跳板机
手动登录的方式:
使用脚本自动登录,效果如下图:
脚本做了:
- 自动输入密码
- 自动输入两步验证码(谷歌验证器 6 位数字动态密码)
totp.py 获取验证码的脚本
这个脚本需要接收一个参数,参数为 TOTP Seed,也就是二维码解析出来的内容。
1 2 3 4 5 6
| import pyotp import sys
totp = pyotp.TOTP(sys.argv[1]) totp_password = totp.now() print(totp_password, end='')
|
登录脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #!/usr/bin/expect -f
trap { set rows [stty rows] set cols [stty columns] stty rows $rows columns $cols < $spawn_out(slave,name) } WINCH
set user root set host 10.0.0.10 set password 123456 set timeout 30
spawn ssh $user@$host -p 60022
expect { "yes/no" {send "yes\r"} "*assword:*" {send "$password\r"} "*OTP verification code*" { set veri_code [ exec sh -c {python3 totp.py <totp_seed>} ] send "${veri_code}\r" } }
interact
|