Shell脚本:expect脚本免交互
expect脚本免交互
- 一、免交互基本概述:
- 1.交互与免交互的区别:
- 2.格式:
- 3.通过read实现免交互:
- 4.通过cat实现查看和重定向:
- 5.变量替换:
- 二、expect安装:
- 1.概述:
- 2.作用:
- 3.expect基本命令:
- 4.实例:
- 5.扩展:
一、免交互基本概述:
1.交互与免交互的区别:
(1)交互:人工发出指令控制程序的运行,程序收到人工相应指令后,做出相应的反应。
(2)免交互:程序按编写好的运行方式,进行指定指令操作,在这个过程中,不需要人工操作,自动化完成。
2.格式:
(1)基本格式:
命令 <<标记 例: wc -l<<wang
> >1
> >2
> >wang
标记 2
(2)总结:
1.标记可以使用任意字符,但必须是合法字符(EOF)
2.结尾的标记一定要顶格写,前面不能有任何字符
3.结尾后也不能有任何字符,包括空格
4.开头标记前后空格会被忽略
5.开头和结尾标记必须一致
3.通过read实现免交互:
[root@test1 opt]# read i <<EOF
> wang,bkpp
> EOF
[root@test1 opt]# echo $i
wang,bkpp
4.通过cat实现查看和重定向:
1.[root@test1 opt]# cat <<EOF #查看
> billkin
> ppkritt
> EOF
billkin
ppkritt
2.[root@test1 opt]# cat <<EOF>wen.txt #重定向
> chanyeol
> baekhyun
> EOF
[root@test1 opt]# cat wen.txt
chanyeol
baekhyun
5.变量替换:
(1)变量替换:
[root@test1 opt]# vim chen.sh
file="chen.sh"
i="the best luck"
cat > $file <<EOF
i like $i
EOF
[root@test1 opt]# sh chen.sh
[root@test1 opt]# cat chen.sh
i like the best luck
(2)整体替换:
[root@test1 opt]# vim chen.sh
var="bkpp is real"
myvar=$(cat <<EOF
the summer in pruket
$var
EOF
)
echo $myvar
[root@test1 opt]# sh chen.sh
the summer in pruket bkpp is real
(3)关闭免交互:
[root@test1 opt]# vim wang.sh
var="GREAT!i am going to school!"
myvar=$(cat <<'EOF'
today is monday
$var
EOF
)
echo $myvar
[root@test1 opt]# sh wang.sh
today is monday $var
(4)补充:
1.[root@test1 opt]# vim kai.sh #去除行首的tab字符,但是不能去除空格
cat <<-'EOF'
kokopop
power
EOF
[root@test1 opt]# sh kai.sh
kokopop
power
2.[root@test1 opt]# vim kai.sh #多行注释
:<<EOF
kokopop
power
EOF
[root@test1 opt]# sh kai.sh
二、expect安装:
1.概述:
(1)建立在tcl之上的一个工具
(2)用于进行自动化控制和测试
(3)解决shell脚本中交互相关的问题
2.作用:
(1)判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回。
(2)只能捕捉由spawn启动的进程的输出。
(3)用于接收命令执行后的输出,然后和期望的字符串匹配。
3.expect基本命令:
(1)send(设置超时时间,指定变量):向进程发送字符串,用于模拟用户的输入:该命令不能自动回车换行,一般要加\r(回车) 或者\n
(2)spawn:用于捕捉关键词,后面常跟一个linux执行命令。
(3)expect:用于判断上层捕捉输出的结果是否有指定字符,有则立即返回,没有则默认等待10s。
(4)exp_continue命令:expect多分支判断时使用。
(5)set命令:可用于设置变量、设置expect超时时间,默认是10s。
(6)结束符: expect eof 结束并返回原来环境,原来主机。interact 结束但是不会返回原来的地方,保持当前状态,当前主机。
4.实例:
(1)用免交互的方式给用户设置密码。
[root@test1 opt]# vim passwd.sh
#!/usr/bin/expect
set timeout 5
spawn passwd lisi
expect "New passwd:"
send "123456\r"
expect "Retype new passwd:"
send "123456\r"
expect eof
[root@test1 opt]# chmod 777 passwd.sh
[root@test1 opt]# ./passwd.sh
(2)用传参方式实现免交互登录:
![10](C:\Users\yuyong\Desktop\笔记\图\10.png)[root@test1 opt]# vim passwd.sh
#!/usr/bin/expect
set timeout 5
set username [lindex $argv 0]
set password [lindex $argv 1]
spawn su - $username
expect "Password:"
send "$password\r"
expect "*]$"
send_user "ok"
expect eof
(3)用嵌入模式实现免交互:
[root@test1 opt]# vim passwd.sh
#!/bin/bash
user=$1
password=$2
useradd $1
/usr/bin/expect <<-EOF
spawn passwd $user
expect "新的 密码:"
send "${password}\r"
expect "重新输入新的 密码:"
send "${password}\r"
expect eof
EOF
[root@test1 opt]# chmod 777 passwd.sh
[root@test1 opt]# ./passwd.sh wang 1233456
useradd:用户“wang”已存在
spawn passwd wang
更改用户 wang 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
(4)用ssh实现免交互:
[root@test1 opt]# vim ssh.sh
#!/usr/bin/expect
set timeout 5
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh $hostname
expect {
"Connection refused" {send_user "ssh访问被拒绝\n"}
"No route to host" {send_user "主机名/IP地址有误\n"}
"yes/no" {send "yes\n";exp_continue}
"password" {send "$password\n"}
}
interact
5.扩展:
(1)监控脚本写一个函数库,用定时任务调用,每月1号执行:
[root@test1 opt]# vim hanshu.sh #创建函数库
fx () {
df -h | awk -F "[ ,%]+" 'NR>1 {if($5>20){print $1"警告!"}}'
}
[root@test1 opt]# vim wang.sh #调用函数
. /opt/hanshu.sh
a=`fx`
echo $a
[root@test1 opt]# crontab -e#创建定时任务
0 0 1 * * /opt/wang.sh
(2)在实现ssh免交互登录的基础上,使它在密码出错的情况下,也可以免交互自动完成:
[root@test1 opt]# vim passwd.sh
#!/usr/bin/expect
set timeout 5
set hostname [lindex $argv 0]
set ip [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $hostname@$ip
expect {
"connection refused" {send_user "ssh访问被拒绝\n"exit}
"No route to host" {send_user "主机名/ip地址有误\n"exit}
"yes/no" {send "yes\n";exp_continue}
"password" {send "$password\n"}
"Permission denied, please try again."
}
interact
[root@test1 opt]# chmod 777 passwd.sh
[root@test1 opt]# ./passwd.sh root 192.168.174.13 123
(3)免交互实现fdisk的磁盘分区,格式化,挂载:
[root@test1 opt]# vim fdisk.sh
#!/bin/bash
/usr/bin/expect <<-EOF
set timeout 5
spawn fdisk /dev/sdb
expect {
"命令(输入 m 获取帮助):" { send "n\n";exp_continue}
"Select (default p): " {send "p\n";exp_continue}
"分区号 (1-4,默认 1):" {send "\n";exp_continue}
"起始 扇区 (2048-41943039,默认为 2048):" {send "\n";exp_continue}
"Last 扇区*" {send "+10G\nw\n";exp_continue}
expect eof
}
EOF
mkfs.xfs -f /dev/sdb1
mkdir /data
mount /dev/sdb1 /data
[root@test1 opt]# chmod 777 fdisk.sh
[root@test1 opt]# ./fdisk.sh