文章目录
一、Here Document 免交互
1.1 概述与格式
- 使用I/O重定向的方式将命令列表提供给交互式程序
- 标准输入的一种替代品
- 语法格式
命令 <<标记
...
...
标记
1.2 使用注意事项
- 标记可以使用任意合法字符
- 结尾的标语一定要顶格写,前面不能有任何字符
- 结尾的标记后面也不能有任何字符(包括空格)
- 开头标记前后的空格会被省略
1.3 示例1:通过read命令接受输入并打印
[root@localhost opt]# cat 00.sh
#!/bin/bash
read -i <<EOF
Hello Word!
EOF
echo $i
[root@localhost opt]# chmod +x 00.sh
[root@localhost opt]# ./00.sh
Hello Word!
1.4 示例2:通过passwd给用户设置密码
[root@localhost opt]# cat 00.sh
#!/bin/bash
passwd zhangsan <<EOF
123456
123456
EOF
[root@localhost opt]# ./00.sh
更改用户 zhangsan 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
1.5 关闭变量替换功能
[root@localhost opt]# cat 00.sh
#!/bin/bash
cat <<'EOF'
$abc
EOF
[root@localhost opt]# ./00.sh
$abc
ps:使用单引号即实现关闭变量替换功能
1.6 多行注释
[root@localhost opt]# cat 00.sh
#!/bin/bash
: <<EOF
this is a test file
EOF
[root@localhost opt]# ./00.sh
[root@localhost opt]#
1.7 去除每行之前的TAB字符
[root@localhost opt]# cat 00.sh
#!/bin/bash
cat <<-'EOF'
this is a test file
EOF
[root@localhost opt]# ./00.sh
this is a test file
ps:‘-’表示抑制行首的TAB作用
二、Expect 免交互
2.1 基本命令
- 建立在tcl之上的一个工具
- 用于进行自动化控制和测试
- 解决shell脚本中交互相关的问题
expect
- 判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回
- 只能捕捉由spawn启动的进程的输出
- 用于接收命令执行后的输出,然后和期望的字符串匹配
send
- 向进程发送字符串,用于模拟用户的输入
- 该命令不能自动回车换行,一般要加/r(回车)
spawn
- 启动进程,并跟踪后续交互信息
结束符
- epect eof:等待执行结束
- interact:执行完成后保持交互状态,把控制权交给控制台
set
- 设置超时时间,过期则继续执行后续指令
- 单位是秒
- timeout -1表示永不超时
- 默认情况下,timeout是10秒
exp_continue
- 允许expect继续向下执行指令
send_user
- 回显命令,相当于echo
接受参数
- Expect脚本可以接受从bash传递的参数
- 可以使用[lindex $argv n]获得
- n从0开始,分别表示第一个,第二个,第三个…参数
2.2 Expect 语法
- 单分支语法
expect "password:" {send "mypassword\r";}
- 多分支模式语法
expect "aaa" {send "AAA\r"}
expect "bbb" {send "BBB\r"}
expect "ccc" {send "CCC\r"}
ps:Send命令不具备回车换行功能,一般要加\r或\n
expect {
"aaa" {send "AAA\r"}
"bbb" {send "BBB\r"}
"CCC" {send "CCC\r"}
}
ps:只要匹配了aaa或bbb或ccc中的任何一个,执行相应的send语句后退出该expect语句
expect {
"aaa" {send "AAA";exp_continue}
"bbb" {send "BBB";exp_continue}
"ccc" {send "CCC"}
}
ps:exp_continue表示继续后面的匹配,如果匹配了aaa,执行完send语句后还要继续向下匹配bbb
2.3 Expect执行方式
#!/usr/bin/expect
#超时
set timeout 20
# 开启日志
log_file test.log
#显示信息
log_user 1
#定义变量
set hostname [lindex $argv 0]
set password [lindex $argv 1]
#追踪指令
spawn ssh root@${hostname}
#捕捉提示信息
expect {
"connecting(yes/no)"
{send "yes\r";exp_continue}
"*password:"
{send "${password}\r";}
}
#转交控制权
interact
2.4 嵌入执行
#/bin/bash
hostname=$1
password=$2
#expect嵌入
/usr/bin/expect <<-EOF
spawn ssh root@${hostname}
#捕捉提示信息
expect {
"connecting(yes/no)"
{send "yes\r";exp_continue}
"*password:"
{send "${password}\r";}
}
expect "*]#"
{send "exit\r"}
expect eof
EOF
三、Expect案例
- 案例一:创建用户并设置密码
#!/bin/bash
user=$1
password=$2
useradd $user
expect <<EOF
spawn passwd $user
expect "New password:"
send "${password}\r"
expect "Retype new password:"
send "${password}\r"
expect eof;
EOF
- 案例二:利用Expect完成SSH登陆过程
#!/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
- 案例三:利用Expect完成FTP登陆过程
#!/bin/expect -f
set timeout 10
spawn ftp 192.168.10.10
expect "Name"
send "ftp\r"
expect "Password:*"
send "\r"
expect "ftp>*"
interact
expect eof