Here Document免交互
Here Document免交互概述
Here Document语法格式与注意事项
注意事项
语法格式及详细注释
基本格式
[ root@localhost mail] # cat > 10. txt << EOF
> QWE123
> qwe321
> qweqwe
> EOF
[ root@localhost mail] # cat 10. txt
QWE123
qwe321
qweqwe
免交互方式实现对行数的统计
[ root@localhost mail] # wc - l << EOF
> 456
> 789
> 123
> 444
> EOF
4
【将要统计的内容置于标记"EOF" 之间,直接将内容传给wc - l进行统计】
将免交互输入的内容通过read命令打印出来
[ root@localhost mail] # read i << EOF
【开头的EOF前后可以有空行,会被自动省略,但结尾的EOF不能有空行】
> take
> easy
> EOF
[ root@localhost mail] # echo $i
take
【read只能接受一行变量】
使用免交互方式通过passwd给用户设置密码
[ root@localhost mail] # passwd qz << QQQ
【标记可以使用任意合法字符(通常为EOF),但前后标记使用的字符需一致】
> 111222
> 111222 【两行一样的代表输入的新密码和确认密码】
> QQQ
更改用户 qz 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
通过免交互方式实现变量的替换
[ root@localhost / ] # cat EOF1. txt
I am going go
[ root@localhost / ] # vim 1. sh
#! / bin/ bash
file= "EOF1.txt" 【中间有符号时最好用引号引起来】
i= go
cat > $file << EOF
I am going to $i
EOF
cat EOF1. txt
通过免交互实现整体赋值给变量
[ root@localhost / ] # . /1. sh
This is Line 1
You are very good!
yes! I am going to home!
[ root@localhost / ] # vim 1. sh
#! / bin/ bash
qz= "yes! I am going to home!"
qz1= $( cat << EOF 【qz1= $( cat << 'EOF' 对标记加单引号,即可关闭变量替换】
This is Line 1
You are very good!
$qz
EOF
)
echo "$qz1" 【这里给变量加上引号即可换行输出】
通过免交互去除每行之前的TAB字符
[ root@localhost / ] # . /1. sh
This is Line 1
You are very good!
yes! I am going to home!
[ root@localhost / ] # vim 1. sh
#! / bin/ bash
qz= "yes! I am going to home!"
qz1= $( cat << - EOF 【在标记前加"-" 即可抑制各行首的TAB键的输出但不能抑制空格】
This is Line 1
You are very good!
$qz
EOF
)
echo "$qz1"
通过免交互实现多行注释
[ root@localhost / ] # . /1. sh
yes! I am going to home!
[ root@localhost / ] # vim 1. sh
#! / bin/ bash
qz= "yes! I am going to home!"
: << EOF
This is Line 1
You are very good!
$qz
EOF
echo "$qz"
Expect概述
Expect基本命令
1.脚本解释器
expect脚本中首先引入文件,表明具体使用的是某一个shell #!/usr/bin/expect
2.spawn
spawn后面通常跟一个linux执行命令,表示开启一个会话、启动进程,并跟踪后续交互信息 例如:spawn passwd qz
3.expect
用于接收命令执行后的输出,然后与期望的字符串匹配 判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回 只能捕捉由spawn启动的进程的输出
4.send
向进程发送字符串,用于模拟用户的输入;该命令不能自动回车执行,需要加\r(回车)或者\n 方式一
expect “密码” {send “abc123\r”} 【同一行时,send部分要有{ }】 方式二
expect “密码” send “$abc123\r” 【不在同一行,换行时,send部分不需要有{ }】 方式三
expect支持多个分支 【只要满足其中一个条件,执行相应的send语句后则退出该expect语句】 expect { “密码1” {send “111222\r”} “密码2” {send “222333\r”} “密码3” {send “333444\r”} }
5.结束符
expect EOF 表示交互结束,等待执行结束,退回到原用户,与spawn对应 例如切换到root用户,expect脚本默认的是等待10s。当执行完命令后,默认停留10s后,自动切回了原用户 interact 执行完成后保持交互状态,把控制权交给控制台,会停留在目标终端而不会退回到原终端,这个时候即可手工操作了,interact后的命令不起作用,比如interact后添加exit,并不会退出root用户。但是如果没有intetact则登录完成后会退出,而不是留在远程终端上 使用interact会保持在终端而不会退回到原终端。例如切换到root用户时,则会一直在root用户状态下;通过ssh链接到另一台服务器时,会一直在目标服务器终端,而不会切回到原服务器 *结束符expect EOF和interact只能二选一
6.set
expect默认的超时时间为10秒,通过set命令可以设置会话超时时间。当设为-1时,则代表不限制超时时间 set timeout 60
7.exp_continue
exp_continue附加于某个expect判断之后,可以使该项被匹配后,还能匹配该expect判断语句内的其他项 exp_continue类似于控制语句中的continue语句。表示允许expect继续向下执行指令 例如:判断交互输出中是否存在yes/no或*assword。如果匹配yes/no则输出yes并再次执行判断 如果匹配*password则输出abc123并结束该段expect语句 注意事项:当使用exp_continue时,如果跟踪的是passwd这样的输入密码后就结束进程的命令,expect{ }外不用再加上expect EOF。因为spawn进程结束后会默认向expect发送EOF,所以再手动加上则会导致后面的expect EOF执行报错
8.send_user
9.接收参数
expect脚本可以接受从bash命令传递的参数,使用[lindex $argv n]获得。其中n从0开始,分别表示第一个,第二个…参数 例如 set hostname [lindex $argv 0] 【相当于hosename=$1的意思】 set password [lindex $argv 1] 【相当于password=$2的意思】
使用expect实现su切换用户
[ root@localhost / ] # exit
exit
[ qz@localhost / ] $ . /expect. sh root 5514
spawn su root
密码:
[ root@localhost / ] # su ok
[ root@localhost / ] # vim expect. sh
#! / usr/ bin/ expect
set timeout 60 【设置超时时间】
set username [ lindex $argv 0 ] 【传入参数,argv代表参数列表】
set password [ lindex $argv 1 ]
spawn su $username 【开始追踪命令】
expect "密码:" 【免交互执行,捕捉信息并匹配。这里使用的是中文“:”】
send "$password\r"
expect "*]#" 【这列的“* ] #”相当于“[ root@localhost / ] #”】
send_user "su ok"
interact 【把控制权交给控制台】
#expect EOF 【2 个结束符都可,但不能同时执行】
使用expect实现创建用户并设置密码
[ root@localhost / ] # . /expect- 1. sh qz1 5514
spawn passwd qz1
更改用户 qz1 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[ root@localhost / ] # su qz
[ qz@localhost / ] $ su qz1
密码:
[ qz1@localhost / ] $
[ qz1@localhost / ] $ vim expect- 1. sh
#! / bin/ bash
user= $1
password= $2 【非交互的命令放在expect外面】
useradd $user
/ usr/ bin/ expect << EOF 【开始免交互执行】
spawn passwd $user 【开启一个进程跟踪passwd命令,expect只能捕获该进程信息】
expect "新"
send "${password}\r"
expect "重"
send "${password}\r"
expect EOF
EOF
使用expect实现ssh自动登录
[ root@localhost ~ ] # . /expect- 2. sh 192.168 .131 .10 5514
spawn ssh 192.168 .131 .10
root@192 .168 .131 .10 's password:
Last login: Fri Mar 19 11 : 59 : 10 2021 from 192.168 .131 .9
[ root@localhost ~ ] # [ root@localhost ~ ] # ifconfig
ens33: flags= 4163 < UP, BROADCAST, RUNNING, MULTICAST> mtu 1500
inet 192.168 .131 .9 netmask 255.255 .255 .0 broadcast 192.168 .131 .255
inet6 fe80: : 3 c3b: eafc: aeef: 6 a67 prefixlen 64 scopeid 0x20 < link>
ether 00 : 0 c: 29 : e3: f1: cd txqueuelen 1000 ( Ethernet)
RX packets 13468 bytes 1176230 ( 1.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6055 bytes 776947 ( 758.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[ root@localhost ~ ] # vim expect- 2. sh
#! / usr/ bin/ expect
set timeout 10
set host [ lindex $argv 0 ]
set passwd [ lindex $argv 1 ]
spawn ssh $host
expect {
"Connection refused" exit 【连接失败的情况,比如对方ssh服务关闭】
"Name or service not know" exit 【找不到服务器,比如输入的IP地址不正确】
"(yes/no)" { send "yse\r" ; exp_continue}
"*password:" { send "${passwd}\r" }
}
#interact
expect EOF 【以expect为结束符。则执行完命令后会自动切回原用户】
[ root@localhost ~ ] # . /expect- 2. sh 192.168 .131 .10 5514
spawn ssh 192.168 .131 .10
root@192 .168 .131 .10 's password:
Last login: Fri Mar 19 11 : 57 : 34 2021 from 192.168 .131 .9
[ root@localhost ~ ] # ifconfig
ens33: flags= 4163 < UP, BROADCAST, RUNNING, MULTICAST> mtu 1500
inet 192.168 .131 .10 netmask 255.255 .255 .0 broadcast 192.168 .131 .255
inet6 fe80: : f8fc: 7087 : 375 : efee prefixlen 64 scopeid 0x20 < link>
ether 00 : 0 c: 29 : 14 : 03 : 40 txqueuelen 1000 ( Ethernet)
RX packets 1272 bytes 147039 ( 143.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 502 bytes 79602 ( 77.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[ root@localhost ~ ] # vim expect- 2. sh
#! / usr/ bin/ expect
set timeout 10
set host [ lindex $argv 0 ]
set passwd [ lindex $argv 1 ]
spawn ssh $host
expect {
"Connection refused" exit
"Name or service not know" exit
"(yes/no)" { send "yse\r" ; exp_continue}
"*password:" { send "${passwd}\r" }
}
interact
#expect EOF