命令 <<标记
...
内容 # 标记之间是传入内容
... 标记
注意事项
[root@localhost ~]#cat <
> hello
> nihao
> EOF
hello
nihao
#覆盖
[root@localhost ~]#cat > txt << EOF
> xxxx
> 1213
> 0258
> EOF
[root@localhost ~]#cat txt
xxxx
1213
0258
#追加
[root@localhost ~]#cat >>txt<
> 4561
> 4789
> EOF
[root@localhost ~]#cat txt
xxxx
1213
0258
4561
4789
常用选项 | 说明 |
---|---|
-a | 内容追加到给定的文件而非覆盖 |
-i | 忽略中断信号 |
[root@localhost ~]#tee<
> 147
> 258
> EOF
147
258
##tee可以直接生成文件,但cat需要">"导出
#统计行数
[root@localhost ~]#wc -l<
> 159
> 123
> 456
> 174
> 11
> 28
> 22
> 08
> eof
8
[root@localhost ~]#read -p "请输入一个数字" ack
请输入一个数字22
[root@localhost ~]#
[root@localhost ~]#echo $ack
22
#修改用户密码
[root@localhost ~]#passwd zhangsan<
> xxxx.1128
> xxxx.1128
> eof
更改用户 zhangsan 的密码 。
新的 密码:重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
Here Document 也支持使用变量,如果标记之间有变量被使用,会先替换变量值。
如果想要将一些内容写入文件,除了常规的方法外,也可以使用 Here Document。
如果写入 的内容中包含变量,在写入文件时要先将变量替换成实际值,在结合 cat 命令完成写入。
[root@localhost data]#vim qw.sh
#!/bin/bash
a="xx.txt"
#新建一个xx.txt文件夹
b="nihao"
cat>$a<<EOF
#用cat命令完成写入
this is $b
EOF
[root@localhost data]#bash qw.sh
[root@localhost data]#cat xx.txt
this is nihao
rpm -q expect
#检查expect是否安装
rpm -q tcl
#检查依赖包tcl是否安装
yum install expect -y
#若是未安装,安装expect
[root@localhost data]#rpm -q expect
expect-5.45-14.el7_1.x86_64
[root@localhost data]#rpm -q tcl
tcl-8.5.13-8.el7.x86_64
#expect和tcl均已安装
[root@localhost data]#which expect
/usr/bin/expect
判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回;只能捕捉有swpan启动的进程输出。
用于接受命令执行后的输出,然后和期望的字符串匹配
1、方式一:
expect "密码" {send "abc123\r"}
#同一行send部分要有{}
2、方式二:
expect "密码"
send "abc123\r"
#换行send部分不需要有{}
3、方式三:
expect 支持多个分支
expect {
#只要匹配了其中一个情况,执行相应的send 语句后退出该expect 语句
"密码1" {send "abc123\r"}
"密码2" {send "123123\r"}
"密码3" {send "123456\r"}
}
expect eof
表示交互结束,等待执行结束,退回到原用户,与spawn对应
比如切换到root用户,expect 脚本默认的等待时间是10s,当执行完命令后,默认停留10s后,自动切回原用户
interact
注意:expect eof 与 interact 只能二选一
注意:使用exp_ continue时,如果跟踪像passwd 这样的输入密码后就结束进程的命令,expect{}外不要 再加上expect eof,因为spawn进程结束后会默认向expect发送eof,,会导致后面的expect eof 执行报错
[root@localhost ~]#vim xxx
#!/usr/bin/expect
set timeout 1
#设置超时等待时间
set username [lindex $argv 0]
set password [lindex $argv 1]
#参数传入
spawn su $username
#开始追踪命令
expect "密码"
send "$password\n"
#免交互执行,捕捉信息并匹配
expect "*]$"
send_user "$username 切换成功!"
#把控制权交给控制台
interact
#等同于expect eof,结束符
#验证,切换用户
[root@localhost ~]#chmod +x xxx
[root@localhost ~]#./xxx zhangsan
spawn su zhangsan
[zhangsan@localhost root]$
[zhangsan@localhost root]$ zhangsan 切换成功!
[zhangsan@localhost root]$
[root@localhost data]#vim ww
#!/usr/bin/expect
set timeout 2
#设置超时时间为2秒,默认情况是10秒
spawn passwd zhangsan
#spawn追踪后面指令产生的交互过程
expect "新的密码"
send "123123\r"
expect "重新输入新的密码"
send "123123\r"
#send 相当于echo,传送在该交互过程中你的预设值
expect eof
#结束符
#验证,用户生成新的密码
[root@localhost data]#expect ww
spawn passwd zhangsan
更改用户 zhangsan 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]#vim qaz
#!/usr/bin/expect
set timeout 2
#超时等待时间2秒
set hostname [lindex $argv 0]
set password [lindex $argv 1]
#参数传入
spawn ssh root@$hostname
#开始追踪命令
expect {
"No route to host" exit
#无法匹配时,直接退出
"Connection refused" exit
#同上
"(yes/no)" {send "yes\r";exp_continue}
"*password" {send "$password\r"}
}
interact
#验证,ssh远程登录
[root@localhost ~]#./qaz 192.168.10.12 123
spawn ssh [email protected]
[email protected]'s password:
Last login: Thu Feb 1 16:24:59 2024 from 192.168.10.11
[root@liuyanfen12 ~]#
[root@localhost ~]#vim cpfq
#!/usr/bin/expect
set timeout 2
set name [lindex $argv 0]
spawn fdisk $name
expect "获取帮助"
send "n\r"
expect "Select"
send "p\r"
expect "分区号"
send "\r"
expect "起始"
send "\r"
expect "Last"
send "+10G\r"
expect "命令"
send "w\r"
interact
[root@localhost ~]#chmod +x cpfq
#添加权限
#验证
[root@localhost ~]#./cpfq /dev/sdb
spawn fdisk /dev/sdb
欢迎使用 fdisk (util-linux 2.23.2)。
更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。
Device does not contain a recognized partition table
使用磁盘标识符 0xae6c7104 创建新的 DOS 磁盘标签。
命令(输入 m 获取帮助):n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
分区号 (1-4,默认 1):
起始 扇区 (2048-41943039,默认为 2048):
将使用默认值 2048
Last 扇区, +扇区 or +size{K,M,G} (2048-41943039,默认为 41943039):+10G
分区 1 已设置为 Linux 类型,大小设为 10 GiB
命令(输入 m 获取帮助):w
The partition table has been altered!
Calling ioctl() to re-read partition table.
正在同步磁盘。
#查看磁盘分区情况(/dev/sdb磁盘有一个10G的分区)
[root@localhost ~]#lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 60G 0 disk
├─sda1 8:1 0 5G 0 part /boot
└─sda2 8:2 0 54G 0 part
├─centos-root 253:0 0 50G 0 lvm /
└─centos-swap 253:1 0 4G 0 lvm [SWAP]
sdb 8:16 0 20G 0 disk
└─sdb1 8:17 0 10G 0 part
sr0 11:0 1 4.2G 0 rom /run/media/root/CentOS 7 x86_64
[root@localhost ~]#vim cjyh
#!/bin/bash
net=192.168.10
password=123
iplist="
12
13
"
for i in $iplist
do
ip=$net.$i
/usr/bin/expect <<EOF
spawn ssh root@$ip
expect {
"(yes/no)"
{send "yes\r";exp_continue}
"*password"
{send "$password\r"}
}
expect "*]#" {send "useradd xxxx\n"}
expect "*]#" {send "echo 123 |passwd xxxx --stdin\r"}
expect "*]#" {send "exit\r"}
expect eof
EOF
done
#验证
[root@localhost ~]#chmod +x cjyh
[root@localhost ~]#./cjyh
spawn ssh [email protected]
[email protected]'s password:
Last login: Thu Feb 1 16:49:54 2024 from 192.168.10.11
[root@liuyanfen12 ~]#useradd xxxx
useradd:用户“xxxx”已存在
[root@liuyanfen12 ~]#echo 123 |passwd xxxx --stdin
更改用户 xxxx 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@liuyanfen12 ~]#exit
登出
Connection to 192.168.10.12 closed.
spawn ssh [email protected]
The authenticity of host '192.168.10.13 (192.168.10.13)' can't be established.
ECDSA key fingerprint is SHA256:XPwaZaTw5yiaSjstVL7RUvtAWazK6knPFGtnu7JUGQ8.
ECDSA key fingerprint is MD5:86:59:fb:79:57:89:ae:83:ef:83:95:66:b0:76:b4:5d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.13' (ECDSA) to the list of known hosts.
[email protected]'s password:
Last login: Wed Jan 17 21:01:17 2024 from 192.168.10.1
[root@liuyanfen13 ~]#useradd xxxx
[root@liuyanfen13 ~]#echo 123 |passwd xxxx --stdin
更改用户 xxxx 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@liuyanfen13 ~]#exit
登出
Connection to 192.168.10.13 closed.