【Shell】expect解决脚本中交互时自动输入的问题

日常和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)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
昨天一个网友问如何能够将输入密码的工作在shell里面自动完成,研究了一下,发现这种交互式的工作,普通的shell实现不了,据说可以借助expect来搞定,所以初步学习了一下expect,成果和大家分享一下: 应用一: 实现从普通用户“test”切换到root用户自动输入root的密码,不用在终端提示符下执行密码输入操作。 步骤: (1)vi autosu.sh (2)#! /usr/bin/expect -f //指定expect工具的路径,如果不清楚具体路径,可以用"which expect"命令来查看。 spawn su - // 在expect 用"spawn"关键字来调用命令“su - ” expect ":" //在执行了su - 命令之后,提示输入密码的提示符。例如你在执行了su - 命令之后,终端里面会出现提示“口令:”,那么你就可以在这里写expect ":",或者expect -exact "口令:" send "rootpasswd\r" //这里expect用send将你的root密码自动输入到上面的提示符之后。 interact //操作完成。 注意:这里强调一下执行脚本要注意的地方,不能按照习惯来用sh ***.sh来这行expect的程序,会提示找不到命令,因为expect用的不是bash所以会报错。执行的候直接./***.sh就可以了。~切记! 应用二: 从普通用户切换到root之后,执行“ls”操作,调用执行aaa.sh,返回执行结果,间隔10S。 #/usr/bin/expect -f spawn su - // 在expect 用"spawn"关键字来调用命令“su - ” expect ":" //在执行了su - 命令之后,提示输入密码的提示符。例如你在执行了su - 命令之后,终端里面会出现提示“口令:”,那么你就可以在这里写expect ":",或者expect -exact "口令:" send "rootpasswd\r" //这里expect用send将你的root密码自动输入到上面的提示符之后。 expect "#" //当遇到提示符以#结尾,即为root权限; send "ls\r" //expect 用spend方法调用ls 命令,并且回车(“\r”) expect "#" send "sh aaa.sh\r" //调用sh aaa.sh,即执行一个脚本文件aaa.sh。 expect "#" send "echo $?\r" sleep 10 interact
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值