条件测试语句

基本语法

(1)test <条件>

(2)[ <条件> ] 需要注意环境前后要有空格

结果:条件非空的话为 True (真),反之为 False(假)

需要注意,在Shell中,通常情况下0为真,其他数值为假(特殊情况如字符串测试等除外)。

1
test homo ; echo $?

文件测试

配合操作符,可以实现文件或者目录类型的检测。

例如,检测当前路径下的 homo 是不是目录?

1
2
3
touch homo
test -d homo ; echo $?
#或使用[ -d homo];echo $?

以下是文件测试操作符与相应说明的对应关系

操作符 说明
-d 测试是否为目录(Directory)
-a 测试目录或文件是否存在(Exist)
-f 测试是否为文件(File)
-r 测试当前用户是否可读(read)
-w 测试当前用户是否可写(write)
-x 测试当前用户是否可执行(excute)

整数测试

整数测试通常用于数值之间的运算,在一些逻辑关系的判断中有应用。

例如判断 1+1+5+4 与 1+9+1 是否相等,可以这么写

1
2
echo $((1+1+5+4)) -eq $((1+9+1)) ; echo $?

以下是关系测试操作符与相应说明的对应关系

操作符 关系运算符 说明
-eq == 等于(Equal)
-ne != 不等于(Not Equal)
-gt > 大于(Greater Than)
-lt < 小于(Lesser Than)
-le <= 小于或等于(Lesser or Equal)
-ge >= 大于或等于(Greater or Equal)

字符串测试

字符串测试操作符的作用包括比较字符串是否相同、测试字符串的长度是否为0。

格式为: [字符串1] 操作符 [字符串2]

以下是字符串测试操作符与相应说明的对应关系

操作符 含义
-z 判断字符串长度是否为 0
-n 判断字符串长度是否为 非0
! 判断两边字符串是否 不相等
= 判断两边字符串是否 相等

逻辑运算符

在Shell条件测试中,使用逻辑运算符实现复杂的条件测试,逻辑运算符用于操作两个变量。

格式为: [表达式1] 操作符 [表达式2]

注意:-a-o 放在 [ ] 里面用,&&|| 放在 [ ] 外面用

以下是逻辑运算操作符与相应说明的对应关系

操作符 含义
-a 或 &&
-o 或 ||
!

if条件

很常见的判断语句,不过要注意Shell中的流程控制不能为空(即如果else分支没有语句执行,就不需要写)。

if单分支

1
2
3
if [条件表达式];then
代码块
fi

if双分支

1
2
3
4
5
6
if [条件表达式]
then
代码块1
else
代码块2
fi

if多分支

1
2
3
4
5
6
7
8
9
if [条件表达式1];then
代码块1
elif [条件表达式2];then
代码块2
elif [条件表达式3];then
代码块3
else
代码块4
fi

case条件

程序会获取case语句中的变量值

  • 如果满足条件表达式1,则执行代码块 1

  • 如果满足条件表达式2,则执行代码块2

  • 如果满足条件表达式3,则执行代码块3

  • 执行到双分号 ;; ,则停止

  • 如果都不满足,则执行*)后面的代码块(上面的双分号会被忽略)

    只要满足一个条件表达式就会跳出case语句主体,执行esac字符后面的命令

1
2
3
4
5
6
7
8
9
10
11
12
13
case 变量值 in
条件表达式1)
代码块1
;;
条件表达式2)
代码块2
;;
条件表达式3)
代码块3
;;
*)
无匹配后代码块
esac

条件表达式的匹配符如下表所示

条件表达式 说明
* 任意字符
? 任意单个字符
[abc] a、b或c其中之一
[a-n] 从a到n的任一字符
| 多重选择

for循环

这是一个在编程语言中常见的循环,当然Shell也是支持的。

语法

  • 当变量值在列表里

    for 循环即执行一次所有命令,使用变量名获取列表中的当前取值

  • in 的取值列表支持替换、字符串和文件名

    如果不用它(in),for循环将使用命令行的位置参数

通常写法

1
2
3
4
for [变量名] in [取值列表]
do
[循环体]
done

一行写法

1
for [变量名] in [取值列表]; do [循环体] done;

💡提醒:写成一行(在终端直接执行)时,需要记得加 ; 符号。

例子

从 1 依次加到 100

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
#for循环之加法
sum=0 #创建结果变量,并赋值为0
#开始for循环(创建i变量,赋值0,当i小于100时,先赋值再自增)
for ((i=0;i<100;i++))
do
#将上一次的结果与当前数值相加
sum=$[${sum}+${i}]
done
#输出结果
echo "从1依次加到100的总和为:" + ${sum}

实现文件中批量用户创建

脚本会读取用户清单文件(格式:[用户名] [密码]),并对文件的文本内容进行切片处理(例如第一个参数为用户名,第二个参数为密码),据此创建用户并配置好密码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
#IFS是内部字段分隔符,此处单词间隔
IFS=$'\n'
#判断脚本是否有参
if [ $# -eq 0 ];then
echo "使用方法: `$0` 用户名单文件"
exit 0
fi
#判断用户名单是否为文件
if [ ! -f $1 ];then
echo "错误:用户名单$1不是文件"
exit 0
fi
#批量创建用户并设置密码
for line in `cat $1`
do
if [ ${#line} -eq 0 ];then #获取文本的长度
echo "清单出现空行,跳过创建。"
continue
fi
#从用户名单中切割出用户名
user=`echo "${line}" | awk '{print $1}'`
#从用户名单中切割出用户密码
pass=`echo "${line}" | awk '{print $2}'`
#查询用户是否存在
id ${user} &> /dev/null
#根据存在与否创建用户并设置密码
if [ $? -eq 0 ];then
echo "提示:用户${user}已经存在!"
else
#创建用户
useradd ${user}
echo "用户${user}已创建完毕!"
#通过管道服务为用户设置密码
echo "${pass} | passwd -stdin ${user} &> /dev/null"
if [ $? -eq 0 ];then
echo "用户${user}的密码配置完毕!"
fi
fi
done
echo "提示:已通过文件$1的用户清单创建用户,并配置密码。"

while循环

while 循环用于不断执行一系列命令,也用于从输入文件中读取数据。

语法

常规写法

1
2
3
4
while [条件表达式]
do
[代码块]
done

无限循环

1
2
3
4
while : #也可写成while true
do
[循环体]
done

例子

从 1 依次加到 100

1
2
3
4
5
6
7
8
9
#!/bin/bash
sum=0
i=1
while [ ${i} -le 100 ]
do
sum=$[${sum}+${i}]
let i=i+1 #也可也使用 i=$[${i}+1]
done
echo "从1依次加到100的总和为:${sum}"

读取键盘输入的信息

1
2
3
4
5
6
7
#!/bin/bash
echo "按下 Crtl和D 退出"
echo -n '你想吃啥: '
while read FOOD
do
    echo "老板,来份:${FOOD}~"
done

until循环

与while循环的处理方式相反,until 循环执行一系列命令直至条件为 true 时停止。

通常情况下,while循环优于until循环。

语法

如果条件表达式的返回值为 false,则继续执行循环体内的语句,否则跳出循环。

1
2
3
4
until [条件表达式]
do
[循环体]
done

例子

遍历输出0~9

1
2
3
4
5
6
7
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo ${a}
a=$[${a}+1]
done

跳出循环

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环。

循环的跳出的命令breakcontinue

break

  • 允许跳出所有循环

continue

  • 仅跳出当前循环