shell免交互--Here Document、Expect

Here Document

使用I/O重定向的方式将命令列表提供给交互式程序,是标准输入的一种替代

语法格式

命令 <<标记
...
...
标记

注意事项

  • 标记可以使用任意合法字符,但首尾要一致
  • 结尾的标记一定要顶格写,前面不能有任意字符
  • 结尾的标记后面也不能有任何字符(包括空格)
  • 开头标记的前后的空格会被省略掉

实现简单的免交互
通过read命令接收输入并打印

[root@localhost ~]# vim do.sh 
#!/bin/bash
#
read i <<EOF    ##这个EOF是可以换的比如DEF
Hi
hello
EOF
echo $i
[root@localhost ~]# ./do.sh       ##执行脚本的时候最好用这种方式
Hi

发现只有第一行被打印了,因为一次交互只对应一行;
设置用户密码

[root@localhost ~]# vim do01.sh 
#!/bin/bash
#
passwd tom <<DEF
123456
123456
DEF
[root@localhost ~]# chmod +x do01.sh 
[root@localhost ~]# ./do01.sh 
更改用户 tom 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

变量的设定

变量替换

生成一个指定内容的文件

[root@localhost ~]# vim do02.sh 

#!/bin/bash
#
filename="none.txt"
dearname="衣羊"
cat > $filename <<EOF
I miss $dearname .
EOF
[root@localhost ~]# ./do02.sh 
[root@localhost ~]# cat none.txt 
I miss 衣羊 .

变量一定要先定义,再调用,不然是会报错的

变量的设定

实现多行内容的赋值

[root@localhost ~]# vim do03.sh
#!/bin/bash
#
name=njit
myvar=$(cat <<EOF
my school is
$name
EOF
)
echo $myvar
[root@localhost ~]# ./do03.sh 
my school is njit

关闭变量的替换功能

[root@localhost ~]# ./do04.sh 
please use the $name
[root@localhost ~]# vim do04.sh 

#!/bin/bash
#
cat <<'EOF'          ##使用单引号将前面的标记引起来,关闭变量替换
please use the $name
EOF

去除每行之前的TAB字符

[root@localhost ~]# vim do05.sh 

#!/bin/bash
#
cat <<-'EOF'    ###-表示抑制行首的TAB
        pelease remove
        $kgc
EOF
[root@localhost ~]# ./do05.sh 
pelease remove
$kgc

实现多行注释

通过Here Document方式使Bash支持多行注释
语法格式

: <<DO
第一行注释
第二行注释
....
DO

多行注释,注释内容不会被执行

[root@localhost ~]# vim do06.sh 
#!/bin/bash
: <<DO
echo "hi"
echo "classmates"
DO
cat <<EOF
please sit down
EOF
[root@localhost ~]# ./do06.sh 
please sit down

Expect

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

安装

yum -y install expect

基本命令

spawn

  • 用于启动进程,并跟踪后续交互信息,用来引导命令的

expect

  • 用来捕捉由命令产生的交互信息,和期望的字符串进行匹配,如果有则立即返回,否则就等待超时时间后返回
  • 只能捕捉由spawn启动的进程的输出

send

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

结束符

  • expect eof 等待执行结束,执行自动化任务时通常使用expect
  • interact 执行完成后保持交互状态,把控制权交给控制台

set

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

exp_continue

  • 允许expect继续向下执行命令

send_user

  • 回显命令,相当于echo

接收参数

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

为了方便可以set filename [lindex $argv 1],之后便可以调用变量filename来表示第一个参数

Expect语法

  • 单一分支语法
expect “password:” {send “123456\r”;} 
  • 多分支模式语法
expect “aaa” {send “AAA\r”;exp_continue}   ##若是没有continue,一旦匹配上就不往下匹配了,会退出expect程序
expect “bbb” {send “BBB\r”}

Expect的执行方式

  • 直接执行

远程登录

[root@localhost expect]# vim expect05.sh 
#!/usr/bin/expect     ###expect的路径
#
set timeout 10
log_file log.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
[root@localhost expect]# ./expect05.sh 20.0.0.61 123456
spawn ssh root@20.0.0.61
root@20.0.0.61's password: 
Last login: Tue Jul 28 11:04:03 2020 from 20.0.0.100
[root@evil ~]# 
  • 嵌入式执行

远程登录后自动登出

[root@localhost expect]# !vim
vim expect07.sh
#!/bin/bash          ###
#
hostname=$1
password=$2
/usr/bin/expect<<-EOF     ###嵌入
spawn ssh root@$hostname
expect {
  "(yes/no)"
  {send "yes\r";exp_continue}
  "password"
  {send "${password}\r";}
}
expect "*]#"
send "exit\r"
expect eof
EOF
[root@localhost expect]# ./expect07.sh 20.0.0.61 123456
spawn ssh root@20.0.0.61
root@20.0.0.61's password: 
Last login: Tue Jul 28 11:06:44 2020 from 20.0.0.100
[root@evil ~]# exit
登出
Connection to 20.0.0.61 closed.

案例

例1:创建用户并设置密码

[root@localhost expect]# vim expect08.sh
#!/bin/bash
#
username=$1
password=$2
useradd $1
/usr/bin/expect<<-EOF
spawn passwd $1
expect {
  "新的 密码"
   {send "$2\r";exp_continue}
  "重新输入新的 密码"
   {send "$2\r";}
}
EOF
[root@localhost expect]# ./expect08.sh wxy 123456
spawn passwd wxy
更改用户 wxy 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

例2:完成SSH登录过程

[root@localhost expect]# vim expect09.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 server not known" exit   ##
   "to continue" {send "yes\r";exp_continue}   ##正常登录
   "password" {send "${password}\r";}
}
interact
exit
[root@localhost expect]# ./expect09.sh 20.0.0.61 123456
spawn ssh 20.0.0.61
root@20.0.0.61's password: 
Last login: Tue Jul 28 11:44:11 2020 from 20.0.0.100
[root@evil ~]# 

例3:FTP登录

[root@localhost expect]# vim expect10.sh 
#!/usr/bin/expect
#
set timeout 10
spawn ftp 20.0.0.61
expect "Name*"
send "ftp\r"
expect "Password:"
send "\r"
expect "ftp>"
interact
expect eof
[root@localhost expect]# ./expect10.sh 
spawn ftp 20.0.0.61
Connected to 20.0.0.61 (20.0.0.61).
220 (vsFTPd 3.0.2)
Name (20.0.0.61:root): ftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> 

记得安装vsftp,启动服务,关闭防火墙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值