背景
在嵌入式开发环境,我们经常需要执行一些特权指令,但是每次执行执行都要手工输入密码(无法在命令行参数里直接传递密码),如果能将这些操作自动化就好了。
解决办法,使用expect程序
expect
命令是一个能自动化执行sudo等交互式命令
的程序。
安装
嵌入式设备一般不能连外网,所以需要离线安装,expect包依赖tcl-expect包,所以需要一起下载一起安装
apt-get download tcl-expect
apt-get download expect
scp tcl-expect_5.45-7_amd64.deb dh@192.168.20.8:/home/dh
scp expect_5.45-7_amd64.deb dh@192.168.20.8:/home/dh
192.168.20.8
是嵌入式设备的IP,将2个deb包拷贝过去后,登录目标设备,执行
sudo dpkg -i tcl-expect_5.45-7_amd64.deb
sudo dpkg -i expect_5.45-7_amd64.deb
将sudo命令封装成expect脚本
expect跟bash
一样,能重定向子进程的输入输出,还包含一些类似test
、read
的内置子命令
#!/usr/bin/expect
set timeout 30
spawn sudo ntpdate 192.168.20.103
expect "sudo"
send "f260\r"
interact
上面这个expect脚本实现ntpdate
命令的自动执行
- set timeout子命令告诉expect等待多久标准输出中出现
特征字符串
,如果超过这个时间仍读不到,则退出 - spawn子命令启动一个交互式程序,本例是sudo程序
- expect子命令检查用户执行的
特征字符串
,本例是“sudo” - send子命令将用户提供的密码"f260"发送给sudo的标准输入
- interact子命令将交互控制从expect返回到bash
执行效果
dh@dh-desktop:~$ ./sync_date.sh
spawn sudo ntpdate 192.168.20.103
[sudo] dh 的密码:
7 Sep 10:47:39 ntpdate[15939]: step time server 192.168.20.103 offset 175771960.146703 sec
总结
expect以牺牲安全性为代价,换来了操作的便利性,在某些场景下这种交换是值得的。