命令 <<标记 EOF
……
……
标记EOF
[root@localhost ~]# read i <
hello world > my name is lisi > EOF > [root@localhost ~]# echo $i > hello world 只能将单行内容重定向到标记前的变量
1.4通过passwd给用户设置密码
示例
#!/bin/bash
passwd liu <
示例
#!/bin/bash
filename="test.txt"
location="kgc"
cat > ${filename} <
用单引号将重定号后面的标记括起来,就能关闭变量替换功能
[root@localhost ~]# num1=100 [root@localhost ~]# num2=200 [root@localhost ~]# echo $num1 100 [root@localhost ~]# echo $num2 200 [root@localhost ~]# num2=$(cat <
300 > $num1 > EOF > ) > [root@localhost ~]# echo $num2 > 300 100 > [root@localhost ~]# echo $num1 > 100 > [root@localhost ~]# num2=$(cat <<'EOF' > 400 > $num1 > EOF > ) > [root@localhost ~]# echo $num2 > 400 $num1
在<<-EOF 标记前添加- 起抑制制表符的作用
示例
#!/bin/bash
echo "hello"
echo "world"
cat <
#!/bin/bash
echo "hello"
echo "world"
cat <<-'EOF'
this is $location .com
EOF
[root@localhost ~]# sh test24.sh
hello
world
this is $location .com
对比总结
1-可以抑制制表符,但不能抑制空格
2用单引号将标记括起来,可以禁用引用变量
Expect是建立在tcl基础上的一个工具,Expect是用来进行自动化控制和测试的工具。主要解决shell脚本中不可交互的问题,对于大规模的linux运维很有帮助
在Linux运维和开发中,我们经常需要远程登录服务器进行操作,在登录的过程是一个交互的过程,可能会需要输入yes/no password等信息。
为了模拟这种输入,可以使用Expect脚本
系统一般不自带,需要自己安装
yum install expect -y
Timeout:指定超时时间,过期则继续执行后续指令
单位是:秒
timeout -1为永不超时
默认情况下,timeout是10秒
exp_continue
允许expect继续向下执行指令
send_user
回显命令,相当于echo
$argv参数数组
Expect脚本可以接受从bash传递的参数,可以使用[lindex $argc n]获得,n从0开始,分别表示第一个,第二个,第三个…参数
arg:参数
Expect脚本的结尾
expect脚本必须以interact或expect eof结束,执行自动化任务通常expect eof就够了
expect eof是在等待结束标志。由spawn启动的命令在结束时会产生一个eof标记,expect eof就是在等待这个标记
单一分支语法
expect "password:" {send "mypassword\r"}
多分支模式语法第一种
expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"} '
send命令不具备回车换行功能,所以需要自己添加\r 或 \n’
多分支模式语法第二种
expect {
"aaa" {send "AAA\r"}
"bbb" {send "BBB\r"}
"ccc" {send "CCC\r"}
}
‘只要匹配了aaa 或bbb或ccc中的任何一个,执行相应的send语句后就会退出该expect语句’
expect {
"aaa" {send "AAA\r";exp_continue}
"bbb" {send "BBB\r";exp_continue}
"ccc" {send "CCC\r"}
}
‘exp_continue表示继续后面的匹配,如果匹配了aaa,执行完send语句后还会继续向下匹配bbb’
‘捕捉内容要用双引号引起来’
‘send要写在{}中,输出信息也要用双引号引起来,分号“;”要写在}里面’
其中,$argv 0 代表位置变量$1
$argv 1 代表位置变量$2
#!/usr/bin/expect 是Expect二进制文件的路径
示例
以ssh远程登录为例
[root@localhost~]#cat test22.sh
#!/usr/bin/expect 由 /usr/bin/expect 来加载脚本
set timeout 60 设置超时时间为60秒(未匹配到登出时间)
log file test.log
log_user 1
set hostname [lindex $argv 0] '变量定义'
set password [lindex $argc 1]
spawn ssh root @$hostname '启动spawn'
expect { '匹配条件'
"(yes/no)"
{send "yes\r";exp_continue}
"*password"
{send "$password\r"}
}
interact '将权限转交控制台'
[root@localhost~]#cat test11.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 'Expect结束标志,EOF前后不能有空格'
执行脚本
[root@localhost ~]# sh test11.sh 14.0.0.8 Abc123
spawn ssh [email protected]
[email protected]'s password:
Last login: Tue Jul 28 09:20:48 2020 from 14.0.0.10
[root@localhost ~]# exit
登出
Connection to 14.0.0.8 closed.
案例一 创建用户并设置密码
#!/bin/bash
user=$1
password=$2
useradd $user
/usr/bin/expect <<-EOF
spawn passwd ${user}
expect {
"新的 密码*:"
{send "${password}";exp_continue}
"重新输入新的 密码:"
{send "${password}\r";}
}
expect "成功"
send "exit\r"
expect eof
EOF
案例二
ssh登录
#!/bin/bash
hostname=$1
password=$2
#experct嵌入
/usr/bin/expect <
ect {
“connecting (yes/no)”
{send “yes\r”;exp_continue}
“password:"
{send “${password}\r”;}
}
expect "]#”
send “exit\r”
expect eof;
EOF
[root@localhost ~]# sh test21.sh 14.0.0.8 Abc123
spawn ssh [email protected]
[email protected]’s password:
Last login: Tue Jul 28 11:15:43 2020 from 14.0.0.8
[root@localhost ~]# exit
登出
Connection to 14.0.0.8 closed.