结构
HereDocument免交互
Here Document常规用法
Expect基本命令
Expect执行方式
Expect案例
Here Document概述
使用I/O重定向的方式将命令列表提供给交互式程序或命令,比如 ftp、oat或read命令。
Here Documen标准输入的一种替代品可以帮助脚本开发人员不必使用临时文件来构建输入信息,而i是直接就地生产出。
语法格式
命令 << 标记
............
标记
特殊字符"<<"在标记和备令之前,这样做的目的是将俞令块的输出重定向到程序或命令的stdin。标记的选择要确保不会出现在其他地方,避免出现混淆:两个标记之间的内容被当做是一个文件并用作"命令"的标准输入。另外Here Locument也可以与非交互式程序和命令一起使用。
Here Document使用注意事项
-
标记可以使用任意合法字符
-
结尾的标记一定要顶格写,前面不能有任何字符
-
结尾的标记后面也不能有任何字符(包括空格)
-
开头标记前后的空格会被省略掉
[root@localhost ~]# cat <<EOF //直接把输入的从命令行输出
hello world
EOF
[ r oot@localhost ~1l cat > name<<EOF //输入保存到文件
liuchun
zhougang
EOF
[root@localhost~]cat name
liuchun
zhougang
[ root localhost ~]# cat >>name <<EOF //追加输入保存到文件
liufei
EOF
[ raot@localhost~].cat name
liuchun
zhougang
liufei
生产:创建yum源
[ root@localhost ~]# cat > test.repo <<EOF
[ test]
name-test
baseurl=file :/// mnt
enabled-1
gpgcheck-О
EOF
另外写法1: cat <<EOF > local.repo
另外写法2:tee testl.txt<<EOF
Here Documen免交互
通过 read 命令接收输入并打印,输入值是两个EOF标记之间的部分,也就是"10",这将作为变量a的值
[ root@lacalhost ~].read a <<EOE
10
EOF
[ root@localhost一]# echo $a
通过 passwd给用户设置密码
给用户创建密码
[root@localhost ~]# passwd zhangsan <<EOF
123456
123456
EOF
更改用户zhangsan的密码
新的密码:无效的密码:密码少于8个字符
重新输入新的密码: passwd:所有的身份验证令牌已经成功更新。
变量设定(支持变量替换)
在写入文件时要先将变量替换成实际值,在结合cat 命令完成写入
[ root@localhost ~] # aa=$ (cat <<EOF //变量替换
$a
EOF
)
echo $aa
支持变量替换
在写入文件时会先将变量替换成实际值,再结合cat命令完成写入
#!/bin/bash
doc_file-"KY17.txt"
i="KY17"
cat > $doc_file <<EOF
welcome to class $i
EOF
this is $i classroom
cat KY17.txt
整体赋值给一个变量,然后通过echo命令将变量值打印出来。
#!/bin/bash
ivar="Great! Beautyful!"
myvar=$(cat <<EOF #将Here Docunent整体城值给变量
This is Line 1
That are sun , Moon and stars.
$ivar #输出时会进行变量替换
EOF
)
echo $myvar
格式控制
关闭变量替换的功能
关闭变量替换的功能,按照字符原本的样子输出,不做任何修改或替换
关闭变量替换
[ root@localhost ~]# aa-$(cat <<'EOF' //关闭变量替换对标记加单引号,即可关闭变量替换
20
$a
EOF
)
echo $aa
#!/bin/bash
i="ky17 class"
kgc=$ (cat <<'EOF' #对标记加单引号,即可关闭变量替换
$i
EOF
)
echo $kgc
去掉每行之前的TAB字符
在第一行的标记前面加'-',这个表示要抑制各行首TAB_的作用。
[root@localhost ~]# vim tab.sh //写一个脚本测试抑制tab键输出
#! /bin/bash
i="ky17 class"
kgc=$ (cat <<'EOF' #对标记加单引号,即可关闭变量替换
$ i
)
echo $kgc
去掉每行之前的TAB字符
在第一行的标记前面加'-',这个表示要抑制各行首TAB的作用。
[root@localhost ~]# vim tab.sh //写一个脚本测试抑制tab键输出
#!/bin/bash
cat <<EOF
hello world
EOF
cat <<-EOF
hello world
EOF
[ root@localhost ~]!bash tab . sh
hello world
hello world
多行注释
Bash 的默认注释是"#”,该注释方法只支持单行注释,在shell脚本的工作中,""右侧的任何字符串,bash都会将其忽略。Here Document的引入解决了多行注释的问题。
:“代表什么都不做的空命令。中间标记区域的内容不会被执行,会被bash 忽略掉,因此可达到批量注释的效果。
!/ bin / bash
a=kgc
:<<=EOF #多行注释以:开头的Here Document标记内容不会被执行
the second comnent.
test line.
echo $a
EOF
echo "exec string . "
基本命令
spawn
启动进程,并跟踪后续交互信息
结束符
expect eof
等待执行结束
interact
执行完成后保持交互状态,把控制权交给控制台
基本命令
set
-
设置超时时间,过期则继续执行后续指令
-
单位是秒
-
timeout -1 表示永不超时
-
默认情况下,timeout是10秒
exp_continue
●允许expect继续向下执行指令
send_user
●回显命令,相当于echo
基本命令
接收参数
-
Expect脚本可以接受从bash传递的参数
-
可以使用[lindex $argv n]获得
-
n从0开始分别表示第一,第二,第三......个参数
执行完成后保持交互状态,把控制权交给控制台,会停留在目标终端而不会退回到原终端,这个时候就可以手工操作了,interact后的命令不起作用,比如interact后添加exit,并不会退出root用户。而如果没有interact则登录完成后会退出..而不是留在远程终端上.
使用interact会保持在终端而不会退回到原终端,比如切换到root用户,会一直在root用户状态下;比如ssh到另一服务器,会一直在目标服务器终端,而不会切回的原服务器。
注意: expeet eof 与 interact只能二选一。
set
expect. 默认的超时时间是10秒,通过 set.命令可以设置会话超时时间,若不限制超时时间则应设置为-1。例: set timeout 30
exp_continu
exp_oontinue
附加于某个expect判断项之后,可以使该项被匹配后,还能继续匹配'该expect-判断语句内的其他项。exp_continue类似于控制语句中的coantinue语句。表示允许expectL继续向下执行指令。
例如:下例将判断交互输出中是否存在yes/no或*pasaword。”如果匹配yes/no则输出 yas并再次执行判断;如果匹A! *password则输出abc123并结束该段cxpect语句。
expect {
"( yes / no) " { send "yes ir" ; exp _continue ; }
"*password" {set timeout 300; send "abc123\r";}
注意:使用exrp continue时,如果跟踪像passwd 这样的输入密码后就结束进程的命令,expect{|外不要再加上expect eof因为spawrn进程结束后会默认向expect发送eof,会导致后面的expect eof执行报错.
注:表示允许用户进行交互操作,一直保持会话连接
send user
send_ user表示回显命令。相当于echo
接收参数
expect脚本可以接受从baah命令行传递的参数,使用[lindex Sargy n]获得。其中n从o开始,分别表示第一个,第二个,第三个.....参数。
例:set. hoatname [ lindex $argv 0]
相当于hostname-$1
set password [ lindex $argv 1]
相当于password-$2
用expect编写脚本
sah无交互登录到远程服务器
[root@sjaerver ~]# vim expect.sh
#!/uar/bin/expect //这里需要用expect白己的解释器,注意不要写成bash否则无法识别
spawn ssh root@192.168.100.100/ /开启一个程序,这个程序是ssh远程登录
expect{
//捕获内容,当出现password的时候,就会向程序发送密码,默认是不换行的,所以需要\r回车换行,多个条件需要花括号括起来,注意格式问题!
"password: "
{send "123456\r: }
}
interact //交互,否则会直接退出远程服务器
[root@sjserver ~]#chmod +x expect.shl //需要加执行权限
[root@sjserver ~]#./expect.sh
spawn ssh root@192.168 . 100 . 100
root@192.168.100.100"s paseword:
Last login: Mon Jul 27 23:31:00 2020 from 192.168.100.120
如果想要在对方服务器上进行一下操作后再退出可执行以下脚本
[rootelocalhost~]#vim expect.sh
#!/usr /bin/expect
spawn ssh root@192.168.245.211
expect {
"password: "
{send "123456\r""; }
}
expect"#" //当铺获到#的时候
send "ls\r" //执行1a命令
send "ifconfig ens33\r" //执行ifconfig ens33命令
sena "exit\r" //执行完exit退出登击
expect eof
//不需要进行交互了,意味着结束expect程序,如果不写的话不会执行操作直接退出,如果不写,写interact也无法在对方机器上执行命令,eof可以替换
定义和引用变量
用set关健字定义变量,变量名和变量的值中间用空格分开,其他用法与shell脚木一致
#!/usr/bin/expect
set user root
set ip 192.168.245.211
set paes 123456
引用位置变量
#!/uer/ bin/cxpect
set user root
set ip [lindex $argv 0] //设置第一个位置变量为ip
set pass [lindex $argv 1] //设置第二个位置变量为登陆密码
spawn ssh $user@$ip
expect {
"password : "
{send " $ass\r" ; }
}
expect "#"
send "ls\r"
send "ifconfig ens33\r"
send "exit \r"
expect eof
[root@localhost -]# /cxpect.sh 192.168.245.211 123456 //执行时需要加位置变量
还可以定义共他参数,例如超时时间,日志等
#超时时间
set timeout 20 //登录超时多少秒退出
set timeout 20 //登陆超时多少秒退出
#开启日志文件
log_file test. log //日志记录操作
#显示信息
log_user 1 //1为屏幕输出信息,o为不输出
ssh免交互登录另外一种写法
#!/ usr/ bin/ expect
set timeout 6o
log_file test.log
log_user 1
set ip [ lindex $argv o]
set password [ lindex $argv 1]
spawn ssh root@$ {ip}
expect {
" (yes/ no ) "
{ send "yeslr" ; exp_continue} "*password"
{ send "$password\r"}
}
interact
嵌入执行模式,将expect过程融入shell 当中,方便执行和处理在sheli脚本中调用expect
1、创建用户并设置用户密码
#! / bin/ bash
username=$1
useradd $username
/usr/bin/expect<<-EOF
spawn passwd $username
expect {
"密码"l/注意:获取的内容和发送的内容不能在同一行否则执行不成功
{ send "123456\r" ; exp_continue }
"新的密码"
{ send "123456、r"; }
)
EOF
验证结果:
[ root@server ~]# . user.sh wangwuspawn passwd wangwu
更改用广wangwu的密码。新的密码:
无效的密码:密码少于8个字符 ;重新输入新的密码
passwd: 所有的身份验证令牌已经成功史新。
#!/ bin/bash
user=$1
password=$2
useradd $uaer
expect<<EOF
spawn passwd $user #开启一个进程跟踪passwd命令,expect只能捕捉该进程信息
expect"新的*" #[匹配输出信息."新的出"
send "${password}\ r" ## 自动输入密码
2、ssh远程到服务器
#!/ bin / bash
expect -c " //需要用expect -c调用expect程序
spawn ssh root@192.168.245.211
expect \"password : "{ send "123456r\” }
interact
"
[ root@localhost ~]# vim expects.sh //不仅停留还要打些命令退出的情况
#!/bin/bash
expect -c "
spawn ssh root@192.168.245.211
expect \ "password : "{ send !"123456lr\ " }
expect \ "]#\"{ send i "ifconfiglri"}
expect \"]#\"{ send i "exit lrl"}
expect eof
"
实现ssh自动登录
#!/usr/bin/expect
set timeout 5
set hostname [ lindex sargv 0]
set password [ lindex Sargv 1]
Spawn ssh $hostname
expect {
"Connection refused" exit #连接失败情况,比如对方ssh服务关闭
"Name or service not known" exit //找不到服务器,比如输入的IP地址不正确
"to continue" { send "yesir" ; exp_continue}
"password: " { send "$password\r"}
}
interact
exit
3.利用expect完成FTP登录过程
#!/usr/bin/expect -f
set timeout 10
spawn ftp 192.168.8.33
expect "Name* "
expect "Password: *"
send " \r"
expect "ftp>* "
interact
expect eof
总结
Here Document使用方法
Expect基本命令
Expect使用方法