shell编程之免交互

文章目录

  • 一.交互、免交互概念
    • 1.交互
    • 2.免交互
  • 二.Here Document 概述及常规用法
    • 1.特点
    • 2.免交互重定向输入
      • 2.1一般格式
      • 2.2 用免交互的方式给用户zhangsan设置密码
      • 2.3 通过cat实现查看和重定向输出到指定文件
    • 3.Here Docunment 变量设定
      • 3.1 变量替换
      • 3.2 整体赋值变量
      • 3.3 关闭免交互
    • 4.去掉每行前面的TAB字符
    • 5.使用免交互方式实现多行注释
  • 三.Expect 概述
    • 1.概述
    • 2.Expect安装
    • 3.expect中的基本命令
      • 3.1 脚不解释器
      • 3.2 spawn
      • 3.3 expect
      • 3.4 send
      • 3.5 结束符
        • 3.5.1 expect_eof——————切换之前的终端用户
        • 3.5.2 interact——————留在当前终端用户
      • 3.6 set
      • 3.7 exp_continue
      • 3.8 send_user
      • 3.9 接收参数
  • 四.典型示例
    • 1.免交互预设值修改用户密码
    • 2.用传参的方式切换用户
    • 3.使用嵌套模式添加用户并输入密码
    • 4.使用免交互的方式实现ssh登录
      • 4.1 指定变量方式
      • 4.2 使用传参的方式进行ssh免交互登录
    • 5.使用fdisk磁盘分区,格式化、挂载

一.交互、免交互概念

1.交互

人工发出指令控制程序的运行,程序在接收到人工相应的指令后,做出相应的反应

2.免交互

程序按照编写好的运行方式进行指定指令的动作,在这过程中,不需要人工进行指定操作,自动化完成

二.Here Document 概述及常规用法

1.特点

(1)使用I/O重定向的方式将命列表提供给交互式程序

(2)口标准输入的一种替代品

(3)语法格式

命令 <<标记

标记

2.免交互重定向输入

2.1一般格式

[root@test1 opt]# read i < zjf,123
> EOF
[root@test1 opt]# echo $i
zjf,123

2.2 用免交互的方式给用户zhangsan设置密码

[root@test1 opt]# useradd zhangsan
[root@test1 opt]# passwd zhangsan < 123
> 123
> EOF
更改用户 zhangsan 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

2.3 通过cat实现查看和重定向输出到指定文件

[root@test1 opt]# cat < this is an apple
> yes
> EOF
this is an apple
yes
[root@test1 opt]# cat <test5.txt
> this is an apple
> yes
> EOF
[root@test1 opt]# cat test5.txt 
this is an apple
yes

3.Here Docunment 变量设定

3.1 变量替换

[root@test1 opt]# vim zz.sh 
[root@test1 opt]# cat zz.sh 
file="xx.txt"
i="banana"
cat > $file <
[root@test1 opt]# vim qq.sh 
[root@test1 opt]# cat qq.sh 
var="GREAT! i am going to school!"
cat > rr.txt <

3.2 整体赋值变量

[root@test1 opt]# vim ztfz.sh
[root@test1 opt]# cat ztfz.sh 
var="GREAT! i am going to school!"
myvar=$(cat <

3.3 关闭免交互

[root@test1 opt]# vim ztfz.sh
[root@test1 opt]# cat ztfz.sh 
var="GREAT! i am going to school!"
myvar=$(cat <<'EOF'
today is monday
$var
EOF
)
echo $myvar
[root@test1 opt]# sh ztfz.sh 
today is monday $var

4.去掉每行前面的TAB字符

tab键的空可以去掉

空格不可以去掉

[root@test2 ~]# cat qd.sh 
cat <<-'EOF'
		zjf
 123
EOF
[root@test2 ~]# sh qd.sh 
zjf
 123

5.使用免交互方式实现多行注释

[root@test2 ~]# cat qd.sh 
: <<-'EOF'
		zjf
 123
EOF
[root@test2 ~]# sh qd.sh 
[root@test2 ~]# 

三.Expect 概述

1.概述

(1)建立在tcl之上的一个工具

(2)用于进行自动化控制和测试

(3)解决shel脚本中交互相关的问题

2.Expect安装

[root@test2 ~]# rpm -q expect
未安装软件包 expect 
[root@test2 ~]# yum -y install expect

3.expect中的基本命令

3.1 脚不解释器

expect 脚本中首先引入文件,表明使用的是哪一个 shell。#!/usr/bin/expectchmod 777 xxx. sh
bash sh

./

3.2 spawn

spawn 后面通常跟一个Linux执行命令,表示开启一个会话、启动进程,并跟踪后续交互信息。例: spawn passwd root

3.3 expect

判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回;只能捕捉由spawn启动的进程的输出:用于接收命令执行后的输出,然后和期望的字符串匹配.

3.4 send

向进程发送字符串,用于模拟用户的输入;该命令不能自动回车换行,
一般要加\r (回车) 或者\n
例:
方式一:
expect"密码”{send “abc123\r”} #同一行send部分要有{}
方式二:

expect"密码”

send “abc123\r” #换行send部分不需要有{ }

方式三:
expect支持多个分支
expect #只要匹配了其中一个情况,执行相应的send语句后退出该expect语句
{
“密码1” {send “abc123\r”}

“密码2” {send “123456\r”}

“密码3” {send “123123\r”}

}

3.5 结束符

3.5.1 expect_eof——————切换之前的终端用户

表示交互结束,等待执行结束,退回到原用户,与spawn对应。比如切换到root用户,expect脚本默认的是等待10s,当执行完命令后,默认停留10s后,自动切回了原用户。

3.5.2 interact——————留在当前终端用户

执行完成后保持交互状态,把控制权交给控制台,会停留在目标终端而不会退回到原终端,这个时候就可以手工操作了,interact后的命令不起作用,比如interact后添加exit,并不会退出root用户而如果没有interact则登录完成后会退出,而不是留在远程终端上。使用interact会保持在终端而不会退回到原终端,比如切换到root用户,会一直在root用户状态下:比如ssh到另一服务器,会一直在目标服务器终端,而不会切回的原服务器。

注意: expect_eof 与 interact 只能二选一。

3.6 set

expect 默认的超时时间是 10 秒,通过 set 命令可以设置会话超时时间,若不限制超时时间则应设置为-1。

例: set timeout 5

3.7 exp_continue

exp_continue 附加于某个 expect 判断项之后,可以使该项被匹配后,还能续匹配该 expet 判断语句内的其他项。exp continue 类似于控制语句中的 continue 语句。表示允许 expect 继续向下执行指令。例如:下例将判断交互输出中是否存在 yes/no 或 password。如果匹配 yes/no 则输出 yes 并再次执行判断:如果匹配password 则输出 abc123 并结束该段 expect 语句。

3.8 send_user

send_user 表示回显命令,相当于 echo。打印的功能

3.9 接收参数

expect 脚本可以接受从bash命令行传递的参数,使用[lindex Sargv n]获得。其中n从0开始,分别表示第一个,第二个,第三个…参数。类似与位置变量,用法相同

例:

set hostname [lindex Sargv 0] ——————相当子 hostname=S1

set password [lindex Sarqy 1]————————相当于 password-S2

注意: expect脚本不能通过bash、 source、来执行(因为这三种方式是调用shell解释器),只能通过绝对路径或相对路径来执行。

四.典型示例

1.免交互预设值修改用户密码

[root@test1 opt]# vim passwd.sh 

#!/usr/bin/expect              #expect的路径指定使用expect编译器
set timeout 3                  #设置退时间

spawn passwd zjf               #开启修改密码

expect "新的 密码:"            #捕获
send "123\r"                  #设置密码
expect "重新输入新的 密码:"     #捕获
send "123\r"                  #设置密码

expect eof                    #退出
[root@test1 opt]# chmod 777 passwd.sh 
[root@test1 opt]# ./passwd.sh
spawn passwd zjf
更改用户 zjf 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

2.用传参的方式切换用户

expect eof 结束语

vim chuancan.sh 
#!/usr/bin/expect
set timeout 3

set username [lindex $argv 0]         #相当于$1
set password [lindex $argv 1]         #相当于$2

spawn su - $username

expect "Password:"
send "$password\r"
expect "*]$"                 #判断捕获 * 表示所有]前的所有
send_user "ok"
expect eof                   #跳出当前终端回到之前终端
[root@test1 opt]# chmod 777 chuancan.sh  
[root@test1 opt]# su - zjf
上一次登录:四 6月  8 19:28:03 CST 2023pts/7 上
[zjf@test1 ~]$ cd /opt/
[zjf@test1 opt]$ ./chuancan.sh lisi 123
spawn su - lisi
密码:
上一次登录:四 6月  8 19:30:44 CST 2023pts/7 上
[lisi@test1 ~]$ ok[zjf@test1 opt]$ 

interact 结束语

[root@test1 opt]# vim chuancan.sh 

#!/usr/bin/expect
set timeout 3

set username [lindex $argv 0]
set password [lindex $argv 1]

spawn su - $username

expect "Password:"
send "$password\r"
expect "*]$"
send_user "ok"
interact
[root@test1 opt]# chmod 777 chuancan.sh 
[root@test1 opt]# su - lisi
[lisi@test1 ~]$ cd /opt/
[lisi@test1 opt]$ ./chuancan.sh zjf 123
spawn su - zjf
密码:
上一次登录:四 6月  8 19:39:13 CST 2023pts/8 上
最后一次失败的登录:四 6月  8 19:43:54 CST 2023pts/2 上
最有一次成功登录后有 2 次失败的登录尝试。
[zjf@test1 ~]$ ok
[zjf@test1 ~]$ 

3.使用嵌套模式添加用户并输入密码

[root@test1 opt]# vim qtmo.sh

#!/bin/bash
user=$1
passwd=$2
useradd $1
/usr/bin/expect <<-EOF
spawn passwd $user
expect "新的 密码:"
send "${passwd}\r"
expect "重新输入新的 密码:"
send "${passwd}\r"
expect eof
EOF
[root@test1 opt]# chmod 777 qtmo.sh 
[root@test1 opt]# ./qtmo.sh ff 123    也可以用sh qtmo.sh dd 123方式
spawn passwd ff
更改用户 ff 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

4.使用免交互的方式实现ssh登录

4.1 指定变量方式

[root@test1 opt]# vim zdssh.sh

#!/usr/bin/expect
set ip 192.168.198.12
set user root
set passwd 000000  
set timeout 5
spawn ssh $user@$ip
expect {
  "yes/no" {send "yes\n";exp_continue}
  "password" {send "${passwd}\n"}
}
interact
[root@test1 opt]# chmod 777 zdssh.sh 
[root@test1 opt]# ./zdssh.sh 
spawn ssh [email protected]
[email protected]'s password: 
Last failed login: Thu Jun  8 22:16:50 CST 2023 from 192.168.198.11 on ssh:notty
There were 4 failed login attempts since the last successful login.
Last login: Thu Jun  8 22:01:11 2023 from 192.168.198.1
[root@test2 ~]#     #如想退出终端在脚本命令中将interact修改为expect eof

4.2 使用传参的方式进行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
[root@test1 opt]# chmod 777 ssh.sh 
[root@test1 opt]# ./ssh.sh 192.168.198.14 123   #未开启的终端地址会直接报错
spawn ssh 192.168.198.14
ssh: connect to host 192.168.198.14 port 22: No route to host
主机名/ip地址有误

使输入密码的时候也免交互输入登录


shell编程之免交互_第1张图片

5.使用fdisk磁盘分区,格式化、挂载

[root@test1 ~]# 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 ~]# ./fdisk.sh

shell编程之免交互_第2张图片

你可能感兴趣的:(linux,vim,运维)