最简单的用法就是只使用 if 语句,它的语法格式为:
if 判断条件
then
执行内容
fi
如果判断条件成立(返回“真”),那么 then 后边的语句将会被执行;如果判断条件不成立(返回“假”),那么不会执行任何语句
也可以将if和then写在同一行:
if 判断条件;then
执行内容
fi
当 if 和 then 位于同一行的时候,这个分号是必须的,否则会有语法错误
做实验进行测试:
(())是一种数学计算命令,它除了可以进行最基本的加减乘除运算,还可以进行大于、小于、等于等关系运算,以及与、或、非逻辑运算。当 a 和 b 相等时,(( $a == $b ))
判断条件成立,进入 if,执行 then 后边的 echo 语句。
在判断条件中也可以使用逻辑运算符,例如:
&&
就是逻辑“与”运算符,只有当&&两侧的判断条件都为“真”时,整个判断条件才为“真”
如果有两个分支,就可以使用 if else 语句,它的格式为:
if 判断条件
then
满足,执行内容1
else
否则,执行内容2
fi
如果判断条件成立,那么 then 后边的执行内容1语句将会被执行;否则,执行 else 后边的执行内容2语句。
我们做一下的测试:
Shell 支持任意数目的分支,当分支比较多时,可以使用 if elif else 结构,它的格式为:
if 判断语句1
then
执行语句1
elif 判断语句2
then
执行语句2
elif 判断语句3
then
执行语句3
……
else
执行语句n
fi
注意:if 和 elif 后边都得跟着 then
整条语句的执行逻辑为:
示例:
case语句与if语句相比是减少了不需要的步骤,使计算效率提高。
case语句的基本格式:
case 表达式 in
匹配模式1)
执行语句1
;;
匹配模式2)
执行语句2
;;
匹配模式3)
执行语句3
;;
……
*)
执行语句n
esac
*)
用来“托底”,万一表达式没有匹配到任何一个模式,*)
部分可以做一些“善后”工作,或者给用户一些提示
可以没有*)
部分。如果 表达式没有匹配到任何一个模式,那么就不执行任何操作
我们现在就来比较测试一下case与if的效率:
写两个功能一样的脚本:
编写case脚本:
case的 表达式 部分支持简单的正则表达式,具体来说,可以使用以下几种格式:
* | 表示任意字符串 |
---|---|
[abc] | 表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个 |
[m-n] | 表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字 |
| | 表示多重选择,类似逻辑运算中的或运算。比如,abc |
关于正则表达式有一下的示例:
#!/bin/bash
printf "Input a character: "
read -n 1 char # 输入一个字符
case $char in
[a-zA-Z]) # 判断是否为字母
printf "\nletter\n"
;;
[0-9]) # 判断是否为数字
printf "\nDigit\n"
;;
[,.?!]) # 判断是否为符号
printf "\nPunctuation\n"
;;
*) # 以上三种都不是的话
printf "\nerror\n"
esac
expect是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预。说白了,expect就是一套用来实现自动交互功能的软件。
在实际操作中,我们运行命令、脚本或程序时,这些命令、脚本或程序都需要从终端输入某些继续运行的指令,而这些输入都需要人为的手工进行。
而利用expect,则可以根据程序的提示,模拟标准输入提供给程序,从而实现自动化交互执行。
expect在yum仓库中存在,可以直接使用yum安装:
首先确定自己的yum仓库存在:
yum clean all # 清空yum仓库
yum repolist # 重新读取网络yum仓库
yum search expect
安装软件包:
yum install expect.x86_64 -y # -y:不用询问直接安装
测试一下命令是否可以使用:
在使用expect时,基本上都是和以下四个命令打交道:
命令 | 作用 |
---|---|
send | 用于向进程发送字符串 |
expect | 用于从进程读取字符串 |
spawn | 启动新的进程 |
interact | 允许用户交互 |
我们通过实验来进行解释:
首先我们编辑一个询问脚本ask.sh
:
这时候就有一个弊端了,如果我们不知道询问脚本有几个问题,我们就不能写出相应的应答脚本应答会出错。
所以我们要是expect语句来进行监控回答:
重新编写应答脚本使用expect语句的方式:
vim answer.exp # 编写expect应答脚本
#!/usr/bin/expect # expect命令执行脚本
sqawn 询问脚本.sh # 监控询问脚本
expect{
# 编写expect语句
"问题中的关键字1" {
send "回答1\r"; exp_continue} # 监控到问题中有关键字1,回答问题1并回车,exp_continue表示如果没有询问这个问题,就继续看下个问题
"问题中的关键字2" {
send "回答2\r"; exp_continue} # 监控到问题中有关键字2,回答问题2并回车,exp_continue如果没有询问这个问题,就继续看下个问题
"问题中的关键字3" {
send "回答3\r"} # 监控到问题中有关键字2,回答问题2并回车,最后一个问题了不用继续监控
}
expect eof # expect语句结束
expect answer.exp # 执行expect应答脚本
如果我们将其中一个应答语句中的exp_continue
位置写错:
这时因为当他检测到old后,作出应答之后没有了exp_continue
,这个语句是用来再次循环expect语句体的。
所以,只有最后一个应答不可以随意交换位置,其他的回答都可以随意交换位置。
还可以通过接收输入值来进行应答:
也可以通过expect脚本来应答命令,如果我们要登录一个主机可以通过ssh命令实现:
总结:
expect | 是自动应答命令,用于交互式命令的自动执行 |
---|---|
spawn | 是expect中的监控程序,其运行后会监控命令提出的交互问题 |
send | 发送问题给交互命令 |
“\r” | 表示回车 |
exp_continue | 表示当问题不存在时继续回答下面的问题 |
expect eof | 表示问题回答完毕退出expect环境 |
interact | 表示问题回答完毕依然保留交互界面 (在ssh登陆时需要使用) |
set NAME [ lindex $argv n ] | 定义变量,NAME是占位符 |
set timeout n | 设定每一个交互问题的等待时间都是n秒,执行后的结果也只等待n秒 |