日常和shell相关的工作中,经常遇到要在脚本中连接其他服务器进行文件传输等操作,这些命令通常会要求和用户交互输入验证 信息,那么在脚本中如何实现自动输入口令之类的信息?这里就要用到expect。
以ubuntu20为例,首先要安装这个软件
apt-get install -y expect
然后才能使用。
本文给出一个postgres自动登录验证的例子:
#!/usr/bin/expect
spawn psql -d postgres -h 192.168.56.22
expect "Password for user postgres:" { send "123\n" }
expect "postgres=#" { send "select 1;\n" }
expect "postgres=#" { send "quit\n" }
expect eof #如果后续不需要用户交互
#interact #如果后续还需要用户交互
这里需要注意的几个点:
1. 执行这个脚本必须要有可执行权限,并通过./方式执行;
chmod +x ***.sh
./***.sh
2. expect不是以bash方式执行,所以脚本第一行必须是 #!/usr/bin/expect
如果想通过bash的方式运行,可以采用下面这个例子的方式
#!/bin/bash
expect << EOF
set timeout -1
spawn pg_dumpall --roles-only --no-sync -f ${PGDATA}/${uuid}.role -h ${HOST} -p ${PORT} -U postgres -l ${DB}
expect "Password:" { send "${PASSWD}\n" }
expect eof
EOF
这个例子中set timeout -1是设置expect超时时间(秒),-1表示永远等待子进程结束。这个在expect中调用其他子进程时很有用,如果超时时间设置过短,就会在子进程结束前中断expect客户端,子进程无法正常结束。
3. spawn是进程起始标识;expect是期待输出内容中包含的字符串;{}中send 后面是要输入的内容,这里要注意使用\n结尾表示输入完毕回车;
4. 进程结束时如果还要继续保持与用户交互,使用interact;不需要保持则使用expect eof结尾
5. expect还支持分支模式,使用\分隔即可,例子:
expect "hi" { send "You said hi\n" } \ "hehe" { send “Hehe yourself\n" } \ "bye" { send "Goodbye\n" }
表示当遇到hi时输出You said hi;当遇到hehe时输出Hehe yourself;以此类推。
更多expect工具的用法可阅读expect详细介绍(中文手册)_程序员_编程符号网 (itfh.cn)