-n 和 -z 在内置测试中的使用 - Bash

fug*_*ive 0 shell bash shell-script test

在 bash 中考虑以下内容:

root@debian-lap:/tmp I=$(echo)
root@debian-lap:/tmp echo "$I"

root@debian-lap:/tmp [ -z "$I" ] && echo "TRUE" || echo "FALSE"
TRUE
Run Code Online (Sandbox Code Playgroud)

这意味着变量 $I 是zero。我可以通过否定测试实现相同的目的,以查看变量是否为非零,!并使测试反向,因此它检查变量zero

root@debian-lap:/tmp ! [ -n "$I" ] && echo "TRUE" || echo "FALSE"
TRUE
root@debian-lap:/tmp
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,当使用-zand时是否有任何特殊情况! -n,反之亦然! -z-n因为它们基本上都在进行相同的测试?

谢谢

Sté*_*las 9

1. [ -z "$var" ]
2. [ ! -n "$var" ]
3. ! [ -n "$var" ]
4. [ ! "$var" ]
5. [ "$var" = '' ]
6. [ ! "$var" != '' ]
7. [ '' = "$var" ]...²

在 POSIX shell 中的所有功能都相同¹。伯恩shell¹没有足够的!关键字,因此将不支持3以上,并有各种各样的bug用特殊值$var(如=-n!...),但在所有7(许多其他shell也有过类似的错误)。

同样,您可以(并且应该)使用[ "$a" = "$b" ] && [ "$x" = "$y" ]代替[ "$a" = "$b" -a "$x" = "$y" ],后者已被弃用且不可靠。

所述!的图3是POSIX壳特征。对于可能想要使用它并否定条件的其他 shell 或非 shell 应用程序,它仍然可以使用test/[实用程序来支持其自己的!运算符(如在 2/6 中)。

test实用程序是由 Unix v7 引入的。在此之前,有一个if实用程序有!, =, !=, -a/ -o,但没有-n/ -z

我想-n/-z中为方便起见,加入(test -n "$var"是用于短形式test "$var" != ''-z被添加的一致性)


¹ 从技术上讲,虽然test/[几乎内置在所有类似 Bourne 的 shell 中,但这并不是 POSIX 强制要求的,并且 Bourne shell 的早期版本没有内置它。虽然 Almquist shell 总是有一个test内置的,但一些 BSD 没有启用它,所以一些 BSD直到 2000 年代才内置[/ 。在任何情况下,无论特定的 shell 是否内置了/命令,所有 POSIX 系统都会在文件系统上有一个/命令(它的行为可能与任何 shell的/ builtin 命令相同,也可能不同)系统)。testsh[test[test[test

² 这并不是说这是唯一可用于测试变量是否为空字符串的命令。

case $var in
  "") ...
esac
Run Code Online (Sandbox Code Playgroud)

是一种不涉及运行任何命令的方式。

expr "x$var" : 'x$' > /dev/null
${var:+"false"}
awk 'BEGIN{exit(ARGV[1] != "")}' "$var"
[ "${#var}" -eq 0 ]
Run Code Online (Sandbox Code Playgroud)

有更多令人费解的方式来做到这一点的例子。

一些类似 Korn 的 shellbash也有一些内置的条件和算术结构,旨在替换[命令 ( [[ -z $var ]], ((${#var} == 0))...)。