条件测试命令

按照文件类型判断

在选项后加文件名,可以判断文件(若存在)类型是否符合条件,若文件不存在直接返回假,符合条件返回真,具体文件类型判断符与 ls 命令结果中文件属性第一位相似

1
2
[选项 文件名]
echo #?
选项 作用
-b 判断文件(若存在(下同))是否为块设备文件(是为真(下同))
-c 判断文件是否为字符设备文件
-d 判断文件是否为目录文件
-e exist 仅判断文件是否存在
-f file 判断文件是否为普通文件
-L 判断文件是否为符号链接文件
-p 判断文件是否为管道文件
-s 判断文件是否为非空(非空为真)
-S 判断文件是否为套接字文件
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
42
43
44
45
-a FILE
如果文件存在,则为 True。
-b FILE
如果文件是特殊块,则为 True。
-c FILE
如果文件是特殊字符,则为 True。
-d FILE
如果文件是目录,则为 True。
-e FILE
如果文件存在,则为 True。
-f FILE
如果文件存在且是普通文件,则为 True。
-g FILE
如果文件是 set-group-id 则为 True。
-h FILE
如果文件是符号链接,则为 True。
-L FILE
如果文件是符号链接,则为 True。
-k FILE
如果文件的 "粘性 "位已设置,则为 True。
-p FILE
如果文件是已命名的管道,则为 True。
-r FILE
如果您可以读取文件,则为 True。
-s FILE
如果文件存在且不为空,则为 True。
-S FILE
如果文件是套接字,则为 True。
-t FD
如果 FD 在终端上打开,则为 True。
-u FILE
如果文件是 set-user-id 则为 True。
-w FILE
如果文件可由您写入,则为 True。
-x FILE
如果文件有执行权限,则为 "true"
-O FILE
如果文件所属者是你,则为 True。
-G FILE
如果文件所属组是你,则为 True。
-N FILE
如果文件自上次读取后已被修改,则为 True。
FILE1 -nt FILE2 如果文件 1 比文件 2 新(根据修改日期),则为True。
FILE1 -ot FILE2 如果文件 1 比文件 2 早,则为 True。
FILE1 -ef FILE2 如果文件 1 是文件 2 的硬链接,则为 True。
1
2
3
4
5
6
7
8
-z STRING
#如果字符串为空,则为 True。
-n STRING
#如果字符串不为空,则为 True。
STRING1 = STRING2 如果字符串相等,则为 True。
STRING1 != STRING2 如果字符串不相等,则为 True。
STRING1 < STRING2 如果 STRING1 按顺序排列在 STRING2 之前,则为 True。
STRING1 > STRING2 如果 STRING1 按顺序排列在 STRING2 之后,则为 True。
1
2
3
4
5
6
7
8
9
10
-o OPTION 
#如果 shell 选项 OPTION 已启用,则为 True。
-v VAR
#如果 shell 变量 VAR 已设置,则为 True。
-R VAR
#如果 shell 变量 VAR 已设置且是名称引用,则为True。
! EXPR
#如果 expr 为假,则为 True。
EXPR1 -a EXPR2 如果 expr1 和 expr2 均为真,则为真。
EXPR1 -o EXPR2 如果 expr1 或 expr2 为真,则为 True。
1
2
3
4
5
6
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于

字符串测试

1
2
3
4
5
6
7
test和 [ ]用法
-z STRING 字符串是否为空,没定义或空为真,不空为假,
-n STRING 字符串是否不空,不空为真,空为假
STRING1 = STRING2 是否等于,注意 = 前后有空格
STRING1 != STRING2 是否不等于
> ascii码是否大于ascii码
< 是否小于
1
2
3
4
5
[[ expression ]] 用法
== 左侧字符串是否和右侧的PATTERN相同
注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
注意: 此表达式用于[[ ]]中;扩展的正则表达式

建议:当使用正则表达式或通配符使用[[ ]],其它情况一般使用 [ ]

文件测试

1
2
3
4
5
6
7
8
-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件-S FILE:是否存在且为套接字文件
1
2
3
4
5
6
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限
1
2
3
4
5
6
7
-s FILE #是否存在且非空
-t fd #fd 文件描述符是否在某终端已经打开
-N FILE #文件自从上一次被读取之后是否被修改过
-O FILE #当前有效用户是否为文件属主-G FILE #当前有效用户是否为文件属组
FILE1 -ef FILE2 #FILE1是否是FILE2的硬链接
FILE1 -nt FILE2 #FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2 #FILE1是否旧于FILE2

按照文件权限判断

同样要在选项后加文件名,有权限为真,无权限或文件不存在为假。(判断的是当前用户对这个文件的权限)

选项 作用
-r 判断对该文件是否有读权限
-w 判断对该文件是否有写权限
-x 判断对该文件是否有执行权限
-u 判断对该文件是否有 SUID 权限
-g 判断对该文件/目录是否有 SGID 权限
-k 判断对该目录是否有 SBIT 权限

比较两个文件的信息

格式:文件 1 [ 选项 ] 文件 2

选项 作用
-nt newer than 判断文件 1 的最后修改时间是否比文件 2 晚,晚为真(0)
-ot older than 判断文件 1 的最后修改时间是否比文件 2 早,早为真(0)
-ef 判断两个文件的 inode 号是否一致,近似为两个文件是否相同

其中,Inode 号是标识文件的序号,两个不同的文件可以名称相同,但 inode 号不能相同,若两个文件为硬链接(保存为副本,同步更新)关系,则两个文件的 inode 号才会相同,其余不同

两个硬链接的文件,除了 inode 号相同外没有任何标志,可以使用这个判断方式判断硬链接

比较两个整数

若为两个变量,不需要声明为整型格式,语法:整数 1 [ 选项 ] 整数 2

选项 作用
-eq equal 判断两个整数是否相等
-ne not equal 判断两个整数是否不相等
-gt greater than 判断整数 1 是否大于整数 2
-lt less than 判断整数 1 是否小于整数 2
-ge greater/equal 判断整数 1 是否大于等于整数 2
-le less/equal 判断整数 1 是否小于等于整数 2

判断字符串相关

语法包含在选项中,注意:两个字符串比较相关的判断符两边都要加空格,否则无论如何,返回值均为真

选项 作用
-z 字符串 判断字符串是否为空
-n 字符串 判断字符串是否非空
字符串 1==字符串 2 判断字符串是否

当字符串是变量时,如果变量没有定义,则同样视作空字符串

两个判断条件的逻辑关系

同时使用两个判断条件时,要注意它们之间的逻辑关系,两个判断关系的格式:条件 1【选项】条件 2

选项 作用
-a 逻辑与,两个条件都成立才成立
-o 逻辑或,两个条件有一个成立就成立
![ 条件 ] 逻辑非,使判断结果取反(注意,!与条件之间有空格)

条件判断语句基础

条件判断语句是编程语言中的基本构造之一,它允许程序在满足特定条件时执行不同的代码块。在 Linux shell 脚本中,常见的条件判断语句包括 <font style="color:rgb(51, 51, 51);background-color:rgb(246, 246, 246);">if</font><font style="color:rgb(51, 51, 51);background-color:rgb(246, 246, 246);">then</font><font style="color:rgb(51, 51, 51);background-color:rgb(246, 246, 246);">else if</font><font style="color:rgb(51, 51, 51);background-color:rgb(246, 246, 246);">else</font> 以及 <font style="color:rgb(51, 51, 51);background-color:rgb(246, 246, 246);">fi</font><font style="color:rgb(51, 51, 51);background-color:rgb(246, 246, 246);">if</font> 的倒置)。这些语句能够根据表达式的真假来决定执行哪些命令。

if 语句

1
2
3
if [ 条件 ]; then
# 条件为真时执行的命令
fi

使用 else

当你需要根据条件的真假来选择两个不同的动作时,可以使用 else 语句:

1
2
3
4
5
if [ 条件 ]; then
# 条件为真时执行的命令
else
# 条件为假时执行的命令
fi

使用 elif

如果你有多个条件需要判断,可以使用 elif(else if 的简写)来扩展 if 语句:

1
2
3
4
5
6
7
if [ 条件1 ]; then
# 条件1为真时执行的命令
elif [ 条件2 ]; then
# 条件1为假且条件2为真时执行的命令
else
# 上述条件都不为真时执行的命令
fi

检查文件属性

检查文件是否存在,是否为空,是否可读等属性是常见的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 检查文件是否存在
if [ -f "/path/to/file" ]; then
echo "文件存在"
else
echo "文件不存在"
fi

# 检查文件是否为空
if [ ! -s "/path/to/file" ]; then
echo "文件为空"
else
echo "文件不为空"
fi

# 检查文件是否可读
if [ -r "/path/to/file" ]; then
echo "文件可读"
else
echo "文件不可读"
fi

比较字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 比较两个字符串是否相等
str1="Hello"
str2="World"
if [ "$str1" == "$str2" ]; then
echo "字符串相等"
else
echo "字符串不相等"
fi

# 检查字符串是否为空
str3=""
if [ -z "$str3" ]; then
echo "字符串为空"
else
echo "字符串不为空"
fi

比较数值

1
2
3
4
5
6
7
8
9
10
# 比较两个数值大小
num1=10
num2=20
if [ $num1 -eq $num2 ]; then
echo "数值相等"
elif [ $num1 -lt $num2 ]; then
echo "num1 小于 num2"
else
echo "num1 大于 num2"
fi

处理用户输入

编写一个脚本时,需要根据用户的输入来决定执行哪些操作

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

# 获取用户输入的参数
user_input=$1

# 使用条件判断来处理不同的输入
if [ "$user_input" == "hello" ]; then
echo "Hello, world!"
elif [ "$user_input" == "bye" ]; then
echo "Goodbye!"
else
echo "Unknown command"
fi

自动化任务中的条件判断

在自动化任务中,条件判断语句可以用来检查任务是否按照预期执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

backup_dir="/path/to/backup"

# 检查备份目录是否存在
if [ ! -d "$backup_dir" ]; then
echo "备份目录不存在,正在创建..."
mkdir -p "$backup_dir"
else
echo "备份目录已存在."
fi

# 执行备份操作
# ...

监控系统资源

条件判断语句也常用于监控系统资源,如 CPU 使用率,磁盘空间等

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

# 获取CPU使用率
cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')

# 判断CPU使用率是否超过预设阈值
threshold=80
if (( $(echo "$cpu_usage > $threshold" | bc -l) )); then
echo "警告: CPU使用率超过${threshold}%!"
else
echo "CPU使用率正常."
fi

网络连接测试

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

# 定义要检查的网络地址
network_address="google.com"

# 使用ping命令测试网络连接
if ping -c 4 "$network_address" &> /dev/null; then
echo "网络连接正常,$network_address 可达。"
else
echo "网络连接异常,$network_address 不可达。"
fi

服务状态检查

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

# 定义要检查的服务名称
service_name="sshd"

# 检查服务是否正在运行
if systemctl is-active --quiet "$service_name"; then
echo "$service_name 服务正在运行。"
else
echo "$service_name 服务未运行,正在尝试重启..."
systemctl restart "$service_name"
fi

文件内容处理

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

# 定义日志文件路径
log_file="/var/log/syslog"

# 检查日志文件中是否包含特定错误信息
error_message="Error: Out of Memory"
if grep -q "$error_message" "$log_file"; then
echo "检测到错误信息,发送通知。"
# 在这里添加发送通知的代码
else
echo "日志文件中没有检测到错误信息。"
fi

系统更新检查

1
2
3
4
5
6
7
8
9
#!/bin/bash

# 检查是否有可用的系统更新
if apt-get update && apt-get upgrade -s | grep -q "upgradable"; then
echo "有可用的系统更新,正在应用更新..."
apt-get upgrade -y
else
echo "当前没有可用的系统更新。"
fi