![在内置测试中使用 -n 和 -z - Bash](https://linux22.com/image/113502/%E5%9C%A8%E5%86%85%E7%BD%AE%E6%B5%8B%E8%AF%95%E4%B8%AD%E4%BD%BF%E7%94%A8%20-n%20%E5%92%8C%20-z%20-%20Bash.png)
在 bash 中考虑以下内容:
root@debian-lap:/tmp I=$(echo)
root@debian-lap:/tmp echo "$I"
root@debian-lap:/tmp [ -z "$I" ] && echo "TRUE" || echo "FALSE"
TRUE
这意味着变量 $I 是zero
。我可以通过否定测试来实现相同的目的,以查看变量是否非零,并使!
测试反向,以便它检查变量zero
root@debian-lap:/tmp ! [ -n "$I" ] && echo "TRUE" || echo "FALSE"
TRUE
root@debian-lap:/tmp
所以,我的问题是,何时使用-z
and是否有任何特殊情况! -n
,反之亦然! -z
,-n
因为它们基本上正在进行相同的测试?
谢谢
答案1
1. [ -z "$var" ]
2. [ ! -n "$var" ]
3. ! [ -n "$var" ]
4. [ ! "$var" ]
5. [ "$var" = '' ]
6. [ ! "$var" != '' ]
7. [ '' = "$var" ]
...²
在 POSIX shell 中功能都是等效的。 Bourne shell 没有!
关键字,因此不支持上面的 3 个,并且除了 7 之外的所有 shell 中都存在各种具有特殊值$var
(如=
、-n
、!
...)的错误(许多其他 shell 也有类似的错误)。
同样,您可以(并且应该)使用[ "$a" = "$b" ] && [ "$x" = "$y" ]
代替[ "$a" = "$b" -a "$x" = "$y" ]
,后者已被弃用且不可靠。
of !
3 是 POSIX shell 功能。test
/实用程序对于可能想要使用它并否定条件的其他 shell 或非 shell 应用程序[
支持其自己的运算符(如 2/6 中所示)仍然有意义。!
该test
实用程序由 Unix v7 引入。在此之前,有一个if
实用程序有!
, =
, !=
, -a
/ -o
,但没有-n
/ -z
。
我想添加-n
/-z
是为了方便(test -n "$var"
是缩写test "$var" != ''
,-z
添加是为了保持一致性)
1 从技术上讲,虽然test
/[
几乎内置在所有类似 Bourne 的 shell 中,但这并不是 POSIX 强制要求的,而且早期版本的 Bourne shell 也没有内置它。虽然 Almquist shell 始终具有test
内置命令,但某些 BSD 并未启用它,因此某些 BSD直到 2000 年代才内置[
/ 。在任何情况下,无论特定 shell 是否内置有/命令,所有 POSIX 系统在文件系统上也会有/命令(其行为可能与系统上任何 shell 的/内置命令相同,也可能不同)。系统)。test
sh
[
test
[
test
[
test
² 这并不是说这是唯一可用于测试变量是否为空字符串的命令。
case $var in
"") ...
esac
是一种不涉及运行任何命令的方法。
expr "x$var" : 'x$' > /dev/null
${var:+"false"}
awk 'BEGIN{exit(ARGV[1] != "")}' "$var"
[ "${#var}" -eq 0 ]
还有更多复杂方法的例子。
一些类似 Korn 的 shellbash
也有一些内置的条件和算术结构体旨在替换[
命令 ( [[ -z $var ]]
, ((${#var} == 0))
...)。
答案2
出于同样的原因,您会得到-n
和,其他测试套件也会给您提供和,或者和。通过避免双重否定,一些测试用例可以让未来的维护者变得更加清晰。另外,正如上面的评论中提到的,与现代 POSIX 不同,古代的版本(即 Bourne 和 Thompson shell)没有关键字来否定表达式的真实性。-z
==
!=
AND
NOT
sh
sh
!
test