跳到内容

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
选项观察
-aAND:如果所有模式都为真,则测试将为真。
-oOR:如果至少有一个模式为真,则测试将为真。

对于内部命令,最好使用此语法

[[ -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