Bash - 测试¶
目标:在本章中,您将学会如何
处理返回码;
测试和比较文件;
测试变量、字符串和整数;
对整数执行运算;
linux, 脚本, bash, 变量
知识:
复杂性:
阅读时间:10 分钟
Shell 执行的命令完成后,都会返回一个返回码(也称为状态或退出码)。
- 如果命令正确执行,约定状态码为零。
- 如果命令在执行过程中遇到问题,其状态码将为非零值。原因有很多:缺少访问权限、文件丢失、输入错误等。
您应该查阅 man command
手册,以了解开发人员提供的返回码的不同值。
返回码不直接可见,但存储在一个特殊变量中:$?
。
mkdir directory
echo $?
0
mkdir /directory
mkdir: unable to create directory
echo $?
1
command_that_does_not_exist
command_that_does_not_exist: command not found
echo $?
127
注意
使用 echo
命令显示 $?
变量的内容,应在您要评估的命令之后立即执行,因为该变量在每次执行命令、命令或脚本后都会更新。
技巧
由于 $?
的值在每次命令执行后都会改变,因此最好将其值放入一个将在之后使用的变量中,用于测试或显示消息。
ls no_file
ls: cannot access 'no_file': No such file or directory
result=$?
echo $?
0
echo $result
2
在脚本中创建返回码也是可能的。为此,只需为 exit
命令添加一个数字参数即可。
bash # to avoid being disconnected after the "exit 2
exit 123
echo $?
123
除了命令的正确执行,shell 还提供了对多种模式进行测试的可能性
- 文件:存在性、类型、权限、比较;
- 字符串:长度、比较;
- 整数:值、比较。
测试结果
$?=0
:测试正确执行并为真;$?=1
:测试正确执行但为假;$?=2
:测试未正确执行。
测试文件类型¶
用于文件的 test
命令语法
test [-d|-e|-f|-L] file
或
[ -d|-e|-f|-L file ]
注意
请注意,在 [
之后和 ]
之前有一个空格。
文件测试命令选项
选项 | 观察 |
---|---|
-e |
测试文件是否存在 |
-f |
测试文件是否存在且为普通文件 |
-d |
检查文件是否存在且为目录 |
-L |
检查文件是否存在且为符号链接 |
-b |
检查文件是否存在且为块设备特殊文件 |
-c |
检查文件是否存在且为字符设备特殊文件 |
-p |
检查文件是否存在且为命名管道(FIFO) |
-S |
检查文件是否存在且为套接字 |
-t |
检查文件是否存在且为终端 |
-r |
检查文件是否存在且可读 |
-w |
检查文件是否存在且可写 |
-x |
检查文件是否存在且可执行 |
-g |
检查文件是否存在且设置了 SGID |
-u |
检查文件是否存在且设置了 SUID |
-s |
测试文件是否存在且非空(大小 > 0 字节) |
示例
test -e /etc/passwd
echo $?
0
[ -w /etc/passwd ]
echo $?
1
已创建一种内部命令,某些 shell(包括 bash)支持该命令,它比外部命令 test
更现代,并提供了更多功能。
[[ -s /etc/passwd ]]
echo $?
1
注意
因此,本章其余部分将使用内部命令。
比较两个文件¶
比较两个文件也是可能的
[[ file1 -nt|-ot|-ef file2 ]]
选项 | 观察 |
---|---|
-nt |
测试第一个文件是否比第二个新 |
-ot |
测试第一个文件是否比第二个旧 |
-ef |
测试第一个文件是否是第二个文件的硬链接 |
测试变量¶
可以测试变量
[[ -z|-n $variable ]]
选项 | 观察 |
---|---|
-z |
测试变量是否为空 |
-n |
测试变量是否非空 |
测试字符串¶
比较两个字符串也是可能的
[[ string1 =|!=|<|> string2 ]]
示例
[[ "$var" = "Rocky rocks!" ]]
echo $?
0
选项 | 观察 |
---|---|
= |
测试第一个字符串是否等于第二个 |
!= |
测试第一个字符串是否与第二个不同 |
< |
测试第一个字符串在 ASCII 顺序上是否在第二个之前 |
> |
测试第一个字符串在 ASCII 顺序上是否在第二个之后 |
整数比较¶
测试整数的语法
[[ "num1" -eq|-ne|-gt|-lt "num2" ]]
示例
var=1
[[ "$var" -eq "1" ]]
echo $?
0
var=2
[[ "$var" -eq "1" ]]
echo $?
1
选项 | 观察 |
---|---|
-eq |
测试第一个数字是否等于第二个 |
-ne |
测试第一个数字是否不等于第二个 |
-gt |
测试第一个数字是否大于第二个 |
-lt |
测试第一个数字是否小于第二个 |
注意
由于 shell 将数值视为普通字符(或字符串),因此对字符的测试可能产生相同的结果,无论它被视为数值还是非数值。
test "1" = "1"
echo $?
0
test "1" -eq "1"
echo $?
0
但测试结果的意义将不同
- 在第一种情况下,它意味着两个字符在 ASCII 表中具有相同的值。
- 在第二种情况下,它意味着两个数字相等。
组合测试¶
组合测试允许您在一个命令中执行多个测试。可以多次测试同一个参数(文件、字符串或数值),也可以测试不同的参数。
[ option1 argument1 [-a|-o] option2 argument 2 ]
ls -lad /etc
drwxr-xr-x 142 root root 12288 sept. 20 09:25 /etc
[ -d /etc -a -x /etc ]
echo $?
0
选项 | 观察 |
---|---|
-a |
AND:当所有模式都为真时,测试为真。 |
-o |
OR:当至少一个模式为真时,测试为真。 |
对于内部命令,最好使用此语法
[[ -d "/etc" && -x "/etc" ]]
测试可以使用圆括号 (
)
进行分组,以赋予它们优先级。
(TEST1 -a TEST2) -a TEST3
!
字符用于执行与选项请求的测试相反的测试
test -e /file # true if file exists
! test -e /file # true if file does not exist
数值运算¶
expr
命令执行整数运算。
expr num1 [+] [-] [\*] [/] [%] num2
示例
expr 2 + 2
4
警告
请注意在运算符两侧加上空格。如果忘记,您将收到错误消息。对于乘法,乘号 *
前面会加上 \
,以避免被错误解释。
选项 | 观察 |
---|---|
+ |
加法 |
- |
减法 |
\* |
乘法 |
/ |
除法商 |
% |
除法模 |
typeset 命令¶
typeset -i
命令将变量声明为整数。
示例
typeset -i var1
var1=1+1
var2=1+1
echo $var1
2
echo $var2
1+1
let 命令¶
let
命令测试字符是否为数字。
示例
var1="10"
var2="AA"
let $var1
echo $?
0
let $var2
echo $?
1
警告
let
命令在评估数值 0
时不返回一致的返回码。
let 0
echo $?
1
let
命令还允许您执行数学运算
let var=5+5
echo $var
10
let
可以被 $(( ))
替换。
echo $((5+2))
7
echo $((5*2))
10
var=$((5*3))
echo $var
15
作者:Antoine Le Morvan
贡献者:Steven Spencer, Ganna Zhyrnova