expect是Unix系统中用来进行自动化控制和测试的软件工具,应用在交互式软件中如telnet,ftp,Passwd,fsck,rlogin,tip,ssh等等。
用法
Linux中我们经常写脚本处理一些繁琐的任务,但不幸的是很多交互式的命令我们不得不人肉响应。
expect可以代替我们实现与系统的交互。
我们可以通过expect实现远程自动更改用户密码,而不需要手动输入旧密码和新密码:
#!/bin/bash
usr_passwd='old_passwd'new_passwd='new_passwd'
whileread ipdo
/usr/bin/expect <
set timeout-1spawnssh -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
EOFdone < /home/mina.xiang/serverip.txt
change-passwd
最近做得稍微复杂一点的,普通用户卸载软驱floppy模块,普通用户权限不够时需要通过sudo执行。
#!/bin/bash
usr_passwd='passwd'
whileread ipdo
/usr/bin/expect <
set timeout-1spawnssh -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
EOFdone < /home/mina.xiang/serverip.txt
remove-floppy
--脚本中调用得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即在等待这个标记.