Shell编程之免交互Here Document与Expect

一、Here Document 概述

  • 使用I/O重定向的方式将命令列表提供给交互式程序。
  • 是标准输入的一种替代品。
    注意事项:
  • 标记可以使用任意合法字符。
  • 结尾的标记一定要顶格写,前面不能有任何字符。(包括空格)
  • 开头标记前后的空格会被省略掉。

1.1 Here Document 基本格式

命令 <<标记
……
……
标记

1.2 Here Document 免交互示例

1.2.1 通过read命令接收输入并打印

[root@promote opt]# vim jiaohu3.sh 
#!/bin/bash
read i <<EOF
Hi
EOF
echo $i
[root@promote opt]# sh jiaohu3.sh 
Hi

1.2.2 通过passwd给用户设置密码

[root@promote opt]# vim jiaohu4.sh 
#!/bin/bash
passwd jerry <<EOF
this_is_password
this_is_password
EOF

1.3 Here Document 变量设定

1.3.1 变量替换

[root@promote opt]# vim jiaohu5.sh 
#!/bin/bash
doc_file="2020.txt"
i="company"
cat >$doc_file <<EOF
take him from home to $i
EOF
[root@promote opt]# cat 2020.txt
take him from home to company

1.3.2 变量设定

[root@promote opt]# vim jiaohu6.sh 
#!/bin/bash
ivar="Great! Beautyful"
myvar=$(cat <<EOF
This is Line 1.
That are Sun,Moin and Stars.
$ivar
EOF
)
echo $myvar
~                                                                                                                                   
~    
[root@promote opt]# sh jiaohu6.sh 
This is Line 1. That are Sun,Moin and Stars. Great! Beautyful

1.3.3 关闭变量替换功能

[root@promote opt]# vim jiaohu7.sh 

#!/bin/bash   
cat <<'EOF' ## 加单引号关闭变量替换功能
This is line.
$num
EOF
~      
[root@promote opt]# sh jiaohu7.sh 
This is line.
$num

1.3.4 去除每行之前的TAB字符

[root@promote opt]# vim jiaohu7.sh 

#!/bin/bash
cat <<-'EOF'
        This is line.
        $num
EOF
~         
[root@promote opt]# sh jiaohu7.sh 
This is line.
$num

1.4 Here Document 多行注释

  • j基本格式
<< DO-NOTHING
第一行注释
第二行注释
DO-NOTHING

二、Expect 概述

  • 建立在tcl之上的一个工具
  • 用于进行自动化控制和测试
  • 解决shell脚本中交互相关的命令

2.1 基本命令

2.1.1 expect

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

2.1.2 send

  • 向进程发送字符串,用于模拟用户的输入。
  • 该命令不能自动回车换行,一般要加\r(回车)。

2.1.3 spawn

  • 启动进程 并跟踪后续交互信息。

2.1.4 结束符号

  • expect eof
    等待执行结束
  • interact
    执行完成后保持交互状态,把控制权交给控制台

2.1.5 set

  • 设置超时时间,过期则继续执行后续指令
  • 单位是秒
  • timeout -1 表示永不超时
  • 默认情况下,timeout是10秒

2.1.6 exp_continue

  • 允许expect继续向下执行

2.1.7 send_user

  • 回显命令,相当于echo

2.1.8 接收参数

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

2.2 Expect语法

2.2.1 单一分支语法

expect “passwd :” {
    
    send “mypassword\r”;}

2.2.2多分支语法

expect {
    
                ## 一旦匹配上其中一个,就跳过下面的字符串   除非后面跟上exp_continue
"aaa"{
    
    send “send “AAA\r”}"
 "bbb"{send “send “BBB\r”}"
 "ccc"{
    
    send “send “CCC\r”}"
}

2.3 Expect执行方式

2.3.1 直接执行

[root@promote opt]# vim jiaohu.sh 

#!/usr/bin/expect  ## 预加载环境 必须写,不然不认识 set这些命令
set timeout 20  ## 超时时间 20S
log_file test.log  ## 日志文件位置
log_user 1 ## 展示日志   开启写1,关闭写0
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh root@${hostname}

expect {
    
    
        "connecting (yes/no)"
        {
    
    send "yes\r";exp_continue}  ## exp_continue 执行完后继续向下执行
        "*password:"
        {
    
    send "${password}\r";}
}
interact    ## 执行完成后保持交互状态,把控制权交给控制台
./vim jiaohu1.sh 192.168.233.100 运行加执行权限用./   不能用sh运行   bash环境运行不了

2.3.2 嵌入执行

[root@promote opt]# vim jiaohu1.sh 

#!/bin/bash ## 预加载环境为bash
hostname=$1
password=$2
/usr/bin/expect <<-EOF  ## 在/usr/bin/expect环境里执行  Expect开始标志
spawn ssh root@${hostname}
expect {
    
    
        "connecting (yes/no)"
        {
    
    send "yes\r";exp_continue}
        "*password:"
        {
    
    send "${password}\r";}
}
expect "*]#"
send "exit\r"
expect eof
EOF 
~               

2.3 案例示例

2.3.1 实现ssh自动登录

  • 首次登录
  • 正常登录
  • 连接被拒绝,可能是ssh没开,或者端口不对,或是防火墙限制
  • 没有连接地址
[root@promote opt]# vim expect_auto_ssh.sh 
#!/usr/bin/expect ## 预加载环境
set timeout 5
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh $hostname
expect {
    
    
        "Connection refused" exit  ## 捕捉字符  出现即退出,不会执行后面的语句
        "Name or service not known" exit  
        "to continue";{
    
    send "yes\r";exp_continue}  ## 第一次连接出现,继续执行下面句子
        "password:";{
    
    send "$password\r"}

}
interact ##将控制权交还控制台 
exit

2.3.2 利用Expect完成FTP登录过程

[root@promote opt]# vim ftp.sh 

#!/usr/bin/expect
set timeout 10
spawn ftp 192.168.233.200
expect {
    
    
        "Name*"
        {
    
    send "ftp\r";exp_continue}
        "Password:*"
        {
    
    send "\r";exp_continue}
        "ftp>*"
        {
    
    send "bye\r"}
}
interact
exit

猜你喜欢

转载自blog.csdn.net/weixin_47219725/article/details/107629210