Bash - 测试¶
目标: 在本章中,您将学习如何
使用返回值;
测试文件并进行比较;
测试变量、字符串和整数;
对数值整数进行操作;
linux, script, bash, variable
知识:
复杂度:
阅读时间: 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 ]
注意
请注意,在[
之后和]
之前有一个空格。
文件test
命令的选项
选项 | 观察 |
---|---|
-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