for语句
for 循环语句:
用于定义循环执行的动作
for循环框架:
for NAME(变量) in {1…10}(变量NAME的值)
do
done
注意:
for循环定义的变量只能其作用于循环内部
几种定义循环变量(计数器)的方式:
for NUM in 1 2 3
# 定义NUM范围1,2,3
for NUM in {1..3}
# 定义NUM范围从1到3
for NUM in {3..1}
# 定义NUM范围从3到1
for NUM in {a..d}
# 定义NUM范围从a到d
for NUM in `seq 1 10`
# 定义NUM范围为seq命令生成的从1到10的序列
seq定义变量的优势在于其可以定义步长:
`seq 1 2 10`筛选出10以内的奇数
(步长为2,起点为1,终点为10,从1开始每隔2取一个值,到10为止;执行结果:1,3,5,7,9)
而{ }大括号内部,只能定义固定的常量
应用示例:
10秒倒计时
#!/bin/bash
for SEC in {10..1}
do
echo -n After ${SEC}s is end 输出倒计时
echo -ne "\r" 用回车换行清除(刷新)上一行命令的输出
sleep 1 执行完毕上面的命令,在此命令处休眠1秒,再接着循环
done
while语句与until语句
while循环,until循环:
(while相当于&&,条件成立时一直循环,直到条件不成立,结束循环,执行下面的命令;util相当于||,条件不成立时一直循环,直到成立)
while true 永远循环
do
内部执行命令
done
util false 永远循环
do
内部执行动作
done
if语句
if 条件判断语句:
(1)
if 判定
then 执行
执行命令 # 判定不成功则无执行
fi 语句结束标志
(2)
if 判断
then 执行
执行动作
elif 分支判定
then 执行
执行动作 # 两个分支都判定不成功,无执行
fi 语句结束标志
(3)
if 判定
then 执行
执行命令
elif 分支判定
then 执行
执行命令
else # 两个分支都判定不成功,执行else命令内容
执行命令
fi 语句结束标志
case
case语句:
可以用于替代部分情况下的多分支if语句
(只能替代判定条件是变量值的匹配的if语句)
类比的机制(对比一次)
点名机制,case去点关键词
case $1 in
westos) $1匹配到westos的情况
echo linux #执行动作
;;
linux) $1匹配到linux的情况
echo westos #执行动作
;;
*) $1匹配不到上面的任意情况,但是一定还能匹配到通配符*,类似于上面的if中的else
echo linux #执行动作
esac case语句结尾
这些都是写在一个case语句里面的
而不像是if语句,实际上if是一个语句,elif是另一个语句了。
因此使用if一个语句一个语句地比对,那么当我们输入的是最后一个情况的话,就要比对n-1次,n-1个语句
expect语句
expect自动问答语句:
自动应答器
用于创建自动应答脚本,模拟完成系统中的交互自动应答
yum install -y expect
生成的不是shell脚本,而是一个expect脚本(.exp文件)
简单的脚本应用:
自动ssh连接远程主机
#!/usr/bin/expect
set timeout 5
set IP [ lindex $argv 0 ]
set PASSWD [ lindex $argv 1 ]
spawn ssh root@IP hostname
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$PASSWD\r" }
}
interact
解释:
#!/usr/bin/expect 必须这样写,否则系统无法识别出这是一个expect脚本执行
set timeout 5 对于一个问题,如果5秒内没有反映,就跳过
set IP [ lindex $argv 0 ] 将该expect脚本后第一串字符作为IP变量的值(相当于是$1)
命令spawn(expect环境中的命令,不是shell中的)
spawn 是 expect 中的监控程序,其运行后会监控命令提出的交互问题
spawn /mnt/ask.sh 监控脚本执行/mnt/ask.sh的命令
(ask.sh 提问;而本应答脚本回答其问题,这两个脚本都需要有执行权限)
(或者不给.exp文件执行权限,而是expect filename 执行该脚本,就类似于sh script.sh)
expect eof 退出expect界面
interact保留交互界面(回答完了问题,留在expect中)
(其用途是在ssh等情况下,连接成功后仍然停留在连接后的界面中)
\转义符号
\r回车符
下图为例:
图一中,创建一个交互式的脚本,演示其手动执行的操作与结果
图三中,是expect命令的使用。
图四中,将expect命令环境中的执行操作,写入exp文件即是自动应答脚本。其执行可以使用expect filename.exp
或者chmod +x filename.exp
+./filename.exp
图五中,将原ask.sh文件中的一个问题注释掉,可以发现,图四中的exp脚本命令会出错
(因为图四中,exp脚本是多条expect语句应答,当其中的expect语句找不到相应问题的关键词,便会出错)
图六中,则是在一个expect语句中应答,“关键词” 对应的send应答
;exp_continue表示应答未结束
将expect环境整合到shell中:
在shell脚本中使用expect进行自动应答
由于是将两个环境整合到一起,在写expect内的代码的时候要顶格写,不能有缩进空格
应用示例:
自动连接172.25.254.6主机,并显示其主机名
vim shell+ssh.exp
#!/bin/bash
Auto_Connect()
{
/usr/bin/expect <<EOF
spawn ssh root@$1 $2
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "westos\r" }
}
expect eof
EOF
}
Auto_Connect 172.25.254.6 hostname | tail -n 1
注意:
expect环境下无法写shell语句,如:for语句
脚本中的语句控制器
exit 脚本退出,程序结束
break 退出当前循环,进行循环以后的代码执行
continue 提前结束本次循环的执行,直接进入下一次循环的执行