1、定义
交互:我们发出指令控制程序的运行,程序在接受到指令之后按照指令的效果做出对应的反应。
免交互:间接的通过第三方把指令传送给程序,不用直接的下达指令
2、Here Document 免交互
这是命令行格式也可以写在脚本当中。通过I/O重定向的方式将命令的列表传送给交互式程序或命令。是标准输入的一种替代品,代替了人工的输入方式
2.1语法格式
命令(linux的系统命令) <<标记
内容1
内容2
内容3
标记
2.2注意事项
(1)标记可以是任意合法字符(一般不用特殊字符,也不以数字开头,通常以EOF作为默认的标记位)
(2)结尾的标记一定要定格写且前面不能有任何字符,空格也不行
(3)结尾的标记后面也不能有任何字符,包括空格
(4)开头的标记前后的空格都会被省略掉
2.3用法
统计行数
[root@test1 ~]# wc -l <<xy102
> 123
> 456
> 789
> xy102
3
read命令输入内容并打印
[root@test1 ~]# read i <<EOF
> ABC
> EOF
[root@test1 ~]# echo $i
ABC
更改用户密码
[root@test1 ~]# passwd dn <<EOF
> 123
> 123
> EOF
更改用户 dn 的密码 。
cat命令+免交互
[root@test1 ~]# cat <<EOF>>test0.txt
> aaa
> bbb
> ccc
> ddd
> EOF
[root@test1 ~]# cat test0.txt
aaa
bbb
ccc
ddd
tee命令
[root@test1 opt]# tee test1.txt<<EOF
> 111
> 222
> 333
> 444
> EOF
111
222
333
444
[root@test1 opt]# cat test1.txt
111
222
333
444
引入变量
file="test1.sh"
i=school
cat > $file <<EOF
I am going to $i
EOF
整体变量赋值
var="Great!I am going to school"
myvar=$(cat <<EOF
this is monday
$var
EOF
)
echo $myvar
3、Expect实现免交互
3.1定义
用tcl语言写的一个工具,主要用于自动化控制和测试,解决shell脚本交互的问题
3.2转义符
\n:换行
\r:回车
\t:相当于一个tab键
\b:表示退格,相当于删除
3.3用法
3.3.1修改用户密码
#!/usr/bin/expect
#声明解释器,不再是默认的bash,需要声明
set timeout 5
#set设置,timeout超时时间,expect有一个默认的超时时间为10秒,设置超时时间为5秒
#也可以作为设置变量spawn passwd dn
#spawn后面用来声明需要执行的命令,开启会话过程,并且跟踪后续的交互信息expect "新的 密码:"
#捕获需要执行的命令行,只要能够捕获即可,不需要完整的,可以用*代表所有send "abc123\r"
#输入指令代码expect "重新输入新的 密码:"
send "abc123\r"
#最后一定要有结束语,结束语只能写一个
expect eof
#交互指令结束之后会退回原用户,切换回之前的用户
interact
#留在当前用户,不会动
免交互只能先赋权再./执行
chomod 777 passwd.sh ./passwd.sh
3.3.2su免交互切换用户
#!/usr/bin/expect
set timeout 5
#传参的方式来表示
set username [lindex $argy 0]
set passwd [lindex $argy 1]
#这种方式就是位置变量
#开始追踪
spawn su - $username
#免交互开始执行
expect "密码"
send "$passwd\r"
#继续捕获
expect "~]$" (普通用户)
【expect "~]#" (管理员)】
send_user "ok"
#send_user = echo 打印指定内容
#结束语
interact
expect eof
3.3.3嵌入执行模式
在shell当中加入expect。涉及到环境切换的场景不建议使用嵌套。ssh su不适合使用嵌入模式
#!/bin/bash
user=$1
password=$2
#非交互命令,使用的是shell
useradd $user
#嵌入免交互
/usr/bin/expect <<-EOF
spawn passwd $user
expect "新的*"
send "$password\r"
expect "重新*"
send "$password\r"
expect eof
EOF
ssh免密登录
#!/usr/bin/expect
set ip 192.168.230.30
set user root
set password 123
set timeout 5
#进入命令行:
spawn ssh $user@$ip
expect {
"yes/no" {send "yes\r";exp_continue}
#这里捕获两次,表示该项被匹配之后,继续匹配其他指定的内容,类似于循环的continue,允许expect语句继续向下执行
"password" {send "$password\r"}
}
interact
主机连接
#!/usr/bin/expect
set timeout 5
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh $hostname
expect {
"No route to host" {send_user "主机名/ip有误\n"}
"Connection refused" {send_user "ssh连接拒绝\n"}
"(yes/no)" {send "yes\r";exp_continue}
"password" {send "$password\r"}
}
interact