一、简介
简介:expect可以用来和脚本中的内容(如read -p、ssh等)自动交互 ,减少手动输入
软件包:yum install expect -y
二、示例
1.首先写一个需要交互的普通脚本
[root@shell mnt]# cat ask.sh
#!/bin/bash
read -p "Pls Input You Name: " NAME
read -p "Pls Input You Age: " AGE
read -p "Pls Input You Class: " CLASS
read -p "Are You Happy?: " MOOD
echo $NAME Is $AGE years old study $CLASS And fell $MOOD
2.创建.exp文件
[root@shell mnt]# cat answer.exp
#!/usr/bin/expect #表示使用expect解释器
spawn /mnt/ask.sh #调用ask.sh脚本
expect "*Name:" #遇到Name:字符的交互语句执行以下输入
send "vaon\r" #输入vaon,\r表示回车
expect "*Age:"
send "18\r"
expect "Class:"
send "linux\r"
expect "Happy?"
send "happy\r"
expect eof
3.增加执行权限
[root@shell mnt]# chmod +x ask.sh
[root@shell mnt]# chmod +x answer.exp
4.执行expect
[root@shell mnt]# /mnt/answer.exp
spawn /mnt/ask.sh
Pls Input You Name: vaon
Pls Input You Age: 18
Pls Input You Class: linux
Are You Happy?: happy
vaon Is 18 years old study linux And fell happy
#########或者使用以下方式#################
.exp文件内容:
[root@shell mnt]# cat answer.exp
#!/usr/bin/expect
set NAME [ lindex $argv 0 ] #表示NAME这个变量取.exp文件后面跟的第一个字符
set AGE [ lindex $argv 1 ] #表示NAME这个变量取.exp文件后面跟的第二个字符
set CLASS [ lindex $argv 2 ] # ...
set MOOD [ lindex $argv 3 ] # ...
spawn /mnt/ask.sh
expect "*Name:"
send "$NAME\r"
expect "*Age:"
send "$AGE\r"
expect "Class:"
send "$CLASS\r"
expect "Happy?"
send "$MOOD\r"
expect eof
执行.exp文件:
[root@shell mnt]# /mnt/answer.exp vaon 18 linux happy #.exp文件后面的内容赋予文件中用set定义变量
#.exp文件执行方式为直接执行即可
spawn /mnt/ask.sh
Pls Input You Name: vaon
Pls Input You Age: 18
Pls Input You Class: linux
Are You Happy?: happy
vaon Is 18 years old study linux And fell happy
三、写一个.exp文件,要求不进行交互ssh一台主机
#!/usr/bin/expect #使用expect解释器
set IP [ lindex $argv 0 ] #表示将.exp文件后面跟的第一个字符定义为IP
set ANSWER [ lindex $argv 1 ] #表示将.exp文件后面跟的第二个字符定义为ANSWER
set PASSWD [ lindex $argv 2 ] #第三个,PASSWD
spawn ssh root@$IP #表示执行spawn后面的命令
expect {
"*connecting" { send "$ANSWER\r" ; exp_continue } #在执行sqawn后面的命令时在匹配到的connecting字符的交互界面里面输入$ANSWER,如果没有这条交互,ecp continue表示跳过继续进行下一条交互界面匹配
"*password:" { send "$PASSWD\r" ; } #在后缀是password:的交互界面里输入$PASSWD
}
expect eof #退出expect环境,interact代表留在expect环境
[root@shell mnt]# chmod +x ssh.exp
[root@shell mnt]# /mnt/ssh.exp 172.25.254.2 yes 123456
[root@station ~]#
#现在已经在172.25.254.2的shell里面了
四、写一个脚本,要求检测1-10号主机网络是否通畅,输出网络正常主机的hostname
#!/bin/bash
Name()
{
expect <<EOF
spawn ssh [email protected].$IP hostname
expect {
"*connecting" { send "yes\r ; exp_continue" }
"*password:" { send "redhat\r" }
}
expect eof
EOF
}
for IP in `seq 1 10`
do
ping -c1 -w1 172.25.254.$IP &>/dev/null
if
[ $? == 0 ]
then
echo "172.25.254.${IP}'s HostName: `Name | grep -E "^spawn\ ssh\ [email protected]|^[email protected]" -v`"
else
echo -e "\033[31m172.25.254.$IP Is Down\033[0m"
fi
done
五、写脚本,要求给1-10号主机自动建立指定的用户、密码,用户密码文件如下:
#!/bin/bash
SSH()
{
expect <<EOC
spawn ssh [email protected].$IP
expect {
"*connecting" { send "yes\r ; exp_continue" }
"*password:" { send "redhat\r" ; }
}
expect "*#"
send "useradd $USERNAME\r"
send "echo $PASSWORD | passwd --stdin $USERNAME\r"
send "exit\r"
expect eof
EOC
}
for ((IP=1;IP<=10;IP++))
do
echo -e "####################\033[34mBegin 172.25.254.${IP}'s CompuTer\033[0m################"
ping -c1 -w1 172.25.254.$IP &>/dev/null
if
[ $? == 0 ]
then
Max_Line=`wc -l /mnt/username | awk '{print $1}'`
for ((N=1;N<=$Max_Line;N++))
do
USERNAME=`sed -n ${N}p /mnt/username`
PASSWORD=`sed -n ${N}p /mnt/password`
SSH | grep -E "^spawn|^root@|^Last\ login|hostname|^logout|closed|exit" -v
done
else
echo -e "\033[31m172.25.254.$IP Is Down,Can't Create User!\033[0m"
fi
echo -e "##########################\033[34m172.25.254.${IP} End\033[0m########################"
done