Shell免交互

一、Here Docunment免交互

针对文本内容进行操作,是标准输入的替代品

不需要进入到文件内部,可以在文件外对文件内容进行操作

二、语法格式

命令 <<标记 (命令是linux命令)

内容
标记  #以什么标记,就以什么结尾

注意事项

  • 1、标记可以使用任意合法字符(字母和数字,一般不适用特殊符号,一般以字母为开头,通常为EOF)
  • 2、结尾的标记一定要顶格写,而且结尾的标记前不能有任何字符(包括空格)
  • 3、开头的标记可以加空格,但是会被自动省略(开头标记前,一般也没有空格)

三、Here Docunment常规用法

3.1 对行数的统计

Shell免交互_第1张图片

3.2 通过read接收输入并赋值给变量

Shell免交互_第2张图片

3.3 用passwd命令给用户设置密码

Shell免交互_第3张图片

3.4 重定向导入文件

Shell免交互_第4张图片

3.5 tee命令直接输入

本身就具有标准输出的作用,可以直接把内容输入到文件当中

Shell免交互_第5张图片

3.6 支持变量替换

Shell免交互_第6张图片

3.7  通过整体赋值给变量

Shell免交互_第7张图片

3.8 关闭变量替换功能

Shell免交互_第8张图片

3.9 去掉文本中行首的tab字符

Shell免交互_第9张图片

Shell免交互_第10张图片

3.10 多行注释

Shell免交互_第11张图片

四、expect免交互

4.1 expect概述

建立在tcl语言基础上的工具,自动化控制和测试,解决shell脚本中交互的问题

[root@pup1 opt]# yum -y install expect
#yum安装会自动解决依赖关系,不需安装tcl

  • 必须赋权执行
  • 可以用.sh做结尾
执行方式:
当前目录:./
绝对路径:/

常用转义字符

\n 相当于换行,回车
\t 制表符,即tab键
\r 回车
\b 退格符,即backspace

4.2 expect基本命令

1、脚本解释器

#!/usr/bin/expect

2、spawn

spawn后一般都是linux的命令,表示开启会话或开启进程,并跟踪后续的交互信息

例:spawn passwd root (开启给root用户修改密码的命令)

3、expect

捕获spawn启动命令的相关内容,进行字符串匹配

4、send

发送指令,模拟用户的输入

示例:

方式一:

expect "密码" {send "123456\r"} #写在同一行必须要用{}

方式二:

expect"密码"
send "123456\r" #换行写不需要{}

方式三:多分支匹配

expect {
"密码1" {send "123456\r"}

"密码2" {send "123456\r"}

"密码3" {send "123456\r"}
}

5、结束符

expect eof

表示交互结束,等待执行结束,退回到原用户

默认等待时间为10s,随即退回之前的终端

interact

表示执行完成之后保持交互状态,把控制权交给控制台,然后停留在目标终端不会退回到原终端

注意:两种结束符只能二选一

6、set

定义变量,设置参数

expect脚本可以接受从bash命令行传递的参数,使用[lindex $argv n] 获得。其中n从0开始,分别表示第一个, 第二个,第三个…参数

示例:

set timeout 5
#expect默认的超时时间为10s,通过set命令设置超时时间
set hostname [lindex $argv 0]
#相当于hostname=$1
set passwd [lindex $argv 1]
#相当于passwd=$2

7、exp_continue

和expect捕获命令结合一起使用,附加在expect判断项之后,匹配到expect的捕获内容之后还能够继续判断expext捕获语句内的其他项

格式:
expect {
"connecting (yes/no)" {send "yes\r"; exp_continue;}
}

注意:expect{}外不要直接街上结束符,因为spawn进程结束后会默认向expect发送eof,会导致后面的结束语执行报错

8、send_user

回显命令,相当于echo,即打印

9、小结练习

示例1:免交互修改用户密码

[root@pup1 opt]# vim passwd.sh

#!/usr/bin/expect
#定义用expect解释器来执行脚本
set timeout 5
#自定义等待时间
spawn passwd ovo
#开启修改密码的进程
expect "New password:"
#捕获的内容是模拟用户需要输入的内容
send "123456\r"
expect "Retype new password:"
send "123456\r"
expect eof
[root@pup1 opt]# chmod 777 passwd.sh 
[root@pup1 opt]# ./passwd.sh 

示例2:切换用户

[root@pup1 opt]# vim su.sh 

#!/usr/bin/expect
set timeout 5
set username [lindex $argv 0]
set password [lindex $argv 1]
#传参,相当于shell的位置变量
spawn su - $username
#开始追踪命令
expect "Password:"
send "$password\r"
expect "*]#"
send_user "ok"
interact

[root@pup1 opt]# chmod 777 su.sh 
[root@pup1 opt]# ./su.sh 

4.3 嵌入执行模式

将expect免交互的过程和shell结合

ssh、su这类涉及到终端切换的命令不建议使用嵌入执行模式

示例:创建用户并创建密码

[root@pup1 opt]# vim qian.sh

#!/bin/bash
user=$1
password=$2
#不需要交互的命令可以放在expect外面执行
useradd $user
#密码环节开始执行免交互
/usr/bin/expect <<-EOF
#开启执行的标志,仅限于嵌入式
spawn passwd $user
expect "New"
send "${password}\r"
expect "Retype"
send "${password}\r"
expect eof
EOF

[root@pup1 opt]# chmod 777 qian.sh 
[root@pup1 opt]# ./qian.sh 

4.4 总结练习

示例1:实现ssh自动登录

[root@pup1 opt]# vim ssh.sh 

#!/usr/bin/expect
set ip 20.0.0.20
set user root
set password 123
#分别声明好连接的ip地址、用户名和密码
set timeout 5
spawn ssh ${user}@${ip}
#开始捕获ssh [email protected]
expect  {
"(yes/no)" {send "yes\n";exp_continue;}
"password" {send "$password\r"}
}
interact

[root@pup1 opt]# chmod 777 ssh.sh 
[root@pup1 opt]# ./ssh.sh 

示例2:用传参的方式实现ssh自动登录

[root@pup1 opt]# vim ssh2.sh

#!/user/bin/expect
#传参的方式执行,可以自定义用户名及密码
set timeout 5
set username [lindex $argv 0]
set password [lindex $argv 1]
#传参
#开启进程,捕获
spawn ssh $username
#定义捕获文件
expect {
"No route to host" {send_user "主机名或ip有误\n"}
"Connection refused" {send_user "ssh访问请求被拒绝\n"}
"(yes/no)" {send "yes\r";exp_continue;}
"password" {send "$password\r"}
}
interact
#interact后面的命令不会再继续执行
exit

[root@pup1 opt]# chmod 777 ssh2.sh 
[root@pup1 opt]# ./ssh2.sh 

实例3: 通过免交互的方式实现硬盘分区、格式化、挂载

[root@pup1 opt]# vim fen.sh

#!/bin/bash
x=$1
/usr/bin/expect <<-EOF
spawn fdisk /dev/sd$x
expect "Command (m for help)"
send "n\r"
expect "Select (default p)"
send "p\r"
expect "Partition number (1-4, default 1)"
send "\r"
expect "First sector"
send "\r"
expect "Last sector"
send "+10G\r"
expect "Last sector"
send "w\r"
expect eof
EOF
partprobe /dev/sd$x
mkfs.xfs /dev/sd${x}1
if [ $? -eq 0 ]
then echo "磁盘格式化完成"
mkdir /data
mount /dev/sd${x}1 /data
else echo "磁盘格式化失败"
fi

 Shell免交互_第12张图片

你可能感兴趣的:(交互)