Shell编程之免交互
Here Document免交互
Here Document概述
1、使用I/O重定向的方式将命令列表提供给交互式程序
2、标准输入的一种替代品
3、语法格式
命令 <<标记
…
…
标记
使用注意事项
1、标记可以使用任意合法字符
2、结尾的标记一定要顶格写,前面不能有任何字符
3、结尾的标记后面也不能有任何字符(包括空格)
4、开头标记前后的空格会被省略掉
Here Document免交互
1、通过read命令接收输入并打印
[root@client3 ~]# vim read.sh
#!/bin/bash
read i <<EOF
hi
EOF
echo $i
[root@client3 ~]# sh read.sh
hi
2、通过passwd给用户设置密码
[root@client3 ~]# useradd nike
[root@client3 ~]# vim passwd.sh
#!/bin/bash
passwd nike <<EOF
123456
123456
EOF
[root@client3 ~]# sh passwd.sh
更改用户 nike 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
Here Document变量设定
1、变量替换
[root@client3 ~]# vim passwd.sh
#!/bin/bash
i=hahaha
j=a.txt
cat>$j<<EOF
you should $i
EOF
[root@client3 ~]# vim replace.sh
[root@client3 ~]# sh replace.sh
[root@client3 ~]# cat a.txt
you should hahaha
2、变量设定
[root@client3 ~]# vim set.sh
#!/bin/bash
i=good
j=$(cat <<EOF
HELLO!
thank you.
$i
EOF
)
echo $j
[root@client3 ~]# sh set.sh
HELLO! thank you. good
Here Document格式控制
1、关闭变量替换功能
[root@client3 ~]# vim shut.sh
#!/bin/bash
i=abc
cat <<'EOF' ## 单引号关闭变量替换
123
$i
EOF
[root@client3 ~]# sh shut.sh
123
$i
2、去除每行之前的TAB字符
[root@client3 ~]# vim tab.sh
#!/bin/bash
i=abc
cat <<-'EOF' ##‘-’表示抑制行首的TAB作用
123123
$i
EOF
[root@client3 ~]# sh tab.sh
123123
$i
Here Document多行注释
通过Here Document使Bash支持多行注释
语法格式
:<<EOF
第一行注释
第二行注释
…
EOF
[root@client3 ~]# vim multi.sh
#!/bin/bash
:<<EOF
123456
ABCabc
EOF
echo "xyz789"
[root@client3 ~]# sh multi.sh
xyz789
Expect概述
Expect
1、建立在tcl之上的一个工具(tcl:命令语言工具)
2、用于进行自动化控制和测试
3、解决shell脚本中交互相关的问题
Expect安装
1、挂载光盘
2、制作本地YUM源
3、执行安装命令 yum -y install expect
yum -y install expect
rpm -qa | grep expect
rpm -qa | grep tcl
调用Expect命令
1、直接执行
#!/usr/bin/expect
2、嵌入执行
#!/bin/bash
.....(/bin/bash可执行的一些内容)
/usr/bin/expect<<-EOF
........(expect可执行的内容)
EOF
基本命令
spawn
启动进程,并跟踪后续交互信息
expect
1、判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回
2、只能捕捉由spawn启动的进程的输出
3、用于接收命令执行后的输出,然后和期望的字符串匹配
send
1、向进程发送字符串,用于模拟用户的输入
2、该命令不能自动回车换行,一般要加\r或\n(回车)
结束符
expect eof ##等待执行结束
interact ##执行完成后保持交互状态,把控制权交给控制台
set
1、设置超时时间,过期则继续执行后续指令
2、单位是秒
3、timeout -1表示永不超时
4、默认情况下,timeout是10秒
exp_continue
允许expect继续向下执行指令
send_user
回显命令,相当于echo
接收参数
1、Expect脚本可以接受从bash传递的参数
2、可以使用[linux $argv n]获得
3、n从0开始,分别表示第一个。第二个,第三个…参数
Expect语法
单一分支语法
expect “password:” {send “mypassword\r”;}
多分支模式语法
模式一:Send命令不具备回车换行功能,一般要加\r或\n
expect “aaa” {send "AAA\r"}
expect "bbb" {send "BBB\r"}
expect "ccc" {send "CCC\r"}
模式二:只要匹配了aaa或bbb或ccc中的任何一个,执行相关的send语句后退出该expext语句
expect {
“aaa” {send "AAA\r"}
"bbb" {send "BBB\r"}
"ccc" {send "CCC\r"}
}
模式三:
expect {
“aaa” {send "AAA";exp_continue}
"bbb" {send "BBB";exp_continue}
"ccc" {send "CCC"}
}
1、创建用户并设置密码
[root@client3 ~]# vim newuser.sh
#!/bin/bash
# 新建用户、设置密码的免交互
hostname=$1
password=$2
useradd $hostname
/usr/bin/expect <<-EOF
spawn passwd $hostname
expect "新的" {send "$password\r"}
expect "重新输入新的" {send "$password\r"}
expect eof
EOF
[root@client3 ~]# sh newuser.sh jack 123456
[root@client3 ~]# sh newuser.sh jack 123456
useradd:用户“jack”已存在
spawn passwd jack
更改用户 jack 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
2、实现ssh自动登录
[root@client3 ~]# more ssh.sh
#!/bin/bash
# ssh免密钥免交互登录
hostname=$1
password=$2
/usr/bin/expect <<-EOF
spawn ssh-keygen -t rsa
expect "(/root/.ssh/id_rsa)" {send "\r"}
expect "(empty for no passphrase)" {send "\r"}
expect "again" {send "\r"}
expect eof
EOF
/usr/bin/expect <<-EOF
spawn ssh-copy-id $hostname
expect "yes/no" {send "yes\r"}
expect "password:" {send "$password\r"}
expect eof
EOF
/usr/bin/expect <<-EOF
spawn ssh root@$hostname
expect "(yes/no)" {send "yes\r"}
expect "password" {send "$password\r"}
expect "*]#" {send "exit\r"}
expect eof
EOF
3、初始化磁盘
[root@client3 ~]# vim newdisk.sh
#!/bin/bash
初始化磁盘、格式化、挂载
/usr/bin/expect<<-EOF
spawn fdisk /dev/sdb
expect {
"命令(输入 m 获取帮助)" {send "n\r";exp_continue}
"Select (default p)" {send "p\r";exp_continue}
"分区号 (1-4,默认 1)" {send "1\r";exp_continue}
"起始 扇区 (2048-41943039,默认为 2048)" {send "\r";exp_continue}
"+size{K,M,G}" {send "\r"}}
expect "命令(输入 m 获取帮助)" {send "p\r";send "wq\r";exp_continue}
EOF
fdisk -l
mkdir /data
mkfs.ext4 /dev/sdb1
mount /dev/sdb1 /data
df -Th
[root@client3 ~]# sh newdisk.sh
......
Allocating group tables: 完成
正在写入inode表: 完成
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root xfs 51G 4.5G 47G 9% /
devtmpfs devtmpfs 897M 0 897M 0% /dev
tmpfs tmpfs 912M 0 912M 0% /dev/shm
tmpfs tmpfs 912M 9.0M 903M 1% /run
tmpfs tmpfs 912M 0 912M 0% /sys/fs/cgroup
/dev/sr0 iso9660 4.3G 4.3G 0 100% /mnt
/dev/sda1 xfs 1014M 179M 836M 18% /boot
/dev/mapper/centos-home xfs 5.0G 39M 5.0G 1% /home
tmpfs tmpfs 183M 16K 183M 1% /run/user/0
/dev/sdb1 ext4 20G 45M 19G 1% /data