Linux自动化命令工具expect
expect是Unix系统中用来进行自动化控制和测试的软件工具,应用在交互式软件中如telnet,ftp,Passwd,fsck,rlogin,tip,ssh等等。
用法
Linux中我们经常写脚本处理一些繁琐的任务,但不幸的是很多交互式的命令我们不得不人肉响应。
expect可以代替我们实现与系统的交互。
我们可以通过expect实现远程自动更改用户密码,而不需要手动输入旧密码和新密码:
#!/bin/bash usr_passwd='old_passwd' new_passwd='new_passwd' while read ip do /usr/bin/expect <<-EOF set timeout -1 spawn ssh -t mina.xiang@$ip expect { "*yes/no*" { send "yes\r";exp_continue } "*assword:" { send "$usr_passwd\r" } } expect "*~]$*" { send "hostname\r" } expect "*~]$*" { send "passwd\r" } expect "(current)*password:" { send "$usr_passwd\r" } expect "New password:" { send "$new_passwd\r" } expect "Retype*password:" { send "$new_passwd\r" } expect "*~]$*" { send "exit\r" } expect eof EOF done < /home/mina.xiang/serverip.txt
最近做得稍微复杂一点的,普通用户卸载软驱floppy模块,普通用户权限不够时需要通过sudo执行。
#!/bin/bash usr_passwd='passwd' while read ip do /usr/bin/expect <<-EOF set timeout -1 spawn ssh -t mina.xiang@$ip expect { "*yes/no*" { send "yes\r";exp_continue } "*assword:" { send "$usr_passwd\r" } } expect "*~]$*" { send "hostname\r" } expect "*~]$*" { send "tty\r" } expect "*~]$*" { send "pwd\r" } expect "*~]$*" { send "sudo modprobe -r floppy\r" } expect "\[sudo\]*mina.xiang:" { send "$usr_passwd\r" } expect "*~]$*" { send "sudo bash -c \"echo 'blacklist floppy' >> /etc/modprobe.d/blacklist-floppy.conf\"\r" } expect "*~]$*" { send "sudo bash -c \"echo 'install floppy /bin/false' >> /etc/modprobe.d/blacklist-floppy.conf\"\r" } expect "*~]$*" { send "sudo cp /boot/initramfs-3.10.0-693.17.1.el7.x86_64.img /boot/initramfs-3.10.0-693.17.1.el7.x86_64.img.$(date +%m-%d-%H%M%S).bak\r" } expect "*~]$*" { send "sudo dracut --omit-drivers floppy -f\r" } expect "*~]$*" { send "sudo sed -i '/^GRUB_CMDLINE_LINUX=/s/\"$/ floppy.blacklist=1 rd.driver.blacklist=floppy\"/' /etc/sysconfig/grub\r" } expect "*~]$*" { send "sudo grub2-mkconfig -o /boot/grub2/grub.cfg\r" } expect "*~]$*" { send "sudo cp /boot/initramfs-3.10.0-693.17.1.el7.x86_64kdump.img /boot/initramfs-3.10.0-693.17.1.el7.x86_64kdump.img.$(date +%m-%d-%H%M%S).bak\r" } expect "*~]$*" { send "sudo sed -i '/^KDUMP_COMMANDLINE_APPEND=/s/\"$/ rd.driver.blacklist=floppy\"/' /etc/sysconfig/kdump\r" } expect "*~]$*" { send "sudo kdumpctl restart\r" } expect "*~]$*" { send "sudo mkdumprd -f /boot/initramfs-3.10.0-693.17.1.el7.x86_64kdump.img\r" } expect "*~]$*" { send "exit\r" } expect eof EOF done < /home/mina.xiang/serverip.txt
--脚本中调用得serverip.txt文件内存放目标机器ip地址,每行一个ip
常用指令
进入expect环境后主要使用的内部命令有三个
- spawn
创建一个新进程,并运行给定的程序,它的主要功能是给运行进程加个壳,用来传递交互指令,expect可以通过spawn监听进程的输出。
- expect
此expect非彼expect,它是expect的内部命令,在expect环境中使用,它用来匹配spawn中进程输出,匹配上了就执行后面的body部分。
- send
用于执行交互动作,改密码时可以send密码,与手工输入密码的动作等效。
expect内部命令会等待目标进程的输出,等待时间默认10秒,没有得到期望值且等待超时后执行下一条命令,也可通过"set timeout number"手动设置时长,“set timeout -1”为永不超时。
expect eof是在等待结束标志。由spawn启动的命令在结束时会产生一个eof标记,expect eof即在等待这个标记.