文章摘要
GPT 4
此内容根据文章生成,仅用于文章内容的解释与总结。

条件测试语句

基本语法

(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循环

语法

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

in 的取值列表支持替换、字符串和文件名;不用取值列表将使用命令行的位置参数

通常写法

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

一行写法

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

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

例子

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

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循环

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

语法

常规写法

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

无限循环

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

例子

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

until循环

与while循环相反,until 循环则默认执行,直到条件满足 true 时停止

语法

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

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

例子

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

跳出循环

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环。break允许跳出所有循环,而continue 仅跳出当前循环。