为什么 [ -n ] false 不像 [ -n "" ]?

RKA*_*RKA 21 bash

我的问题是关于这段代码产生的返回值:

if [ -n ]; then echo "true"; else echo "false"; fi
Run Code Online (Sandbox Code Playgroud)

这打印true.

它的补充测试[ -z ]还使用打印true

if [ -z ]; then echo "true"; else  echo "false"; fi
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,为什么[ -n ]测试假设根本没有通过的字符串值,作为非空?

下面的代码打印false. 这是预期的,因为传递的字符串值为空且长度为零。

if [ -z ]; then echo "true"; else  echo "false"; fi
Run Code Online (Sandbox Code Playgroud)

Eli*_*gan 31

[ -n ]不使用-n测试。

-n[ -n ]是不是在所有的测试。当[和之间只有一个参数时],该参数是一个字符串,用于测试它是否为空。即使该字符串有一个前导-,它仍然被解释为一个操作数,而不是一个测试。由于字符串-n不是空的-它包含两个字符,-并且n不是零characters--[ -n ]计算结果为True。

正如Ignacio Vazquez-Abrams 所说, wherestring是单个参数,对stringin执行的测试与由 对其执行的测试相同。当恰好是 时,没有什么特别的事情发生。的在与所述第二中是简单的字符串被测试空虚。[ string ][ -n string ]string-n-n[ -n ]-n[ -n -n ]

[和之间只有一个参数时],该参数始终是一个要测试是否为非空的字符串,即使它恰好与测试名称相同。类似地,当[and]和第一个 is之间有两个参数时-n,第二个始终是一个要测试非空性的字符串,即使它碰巧与测试名称相同。这仅仅是因为 for 的语法[坚持认为[]或之后的单个参数-n是字符串操作数。

出于同样的原因,[ -n ]不使用-n测试,[ -z ]不使用-z测试。


您可以通过查看有关[inbash的帮助来了解有关in的更多信息。请注意,这是一个内置的 shell

$ type [
[ is a shell builtin
Run Code Online (Sandbox Code Playgroud)

因此,您可以运行help [以获取有关它的帮助:

$ help [
[: [ arg... ]
    Evaluate conditional expression.

    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.
Run Code Online (Sandbox Code Playgroud)

有关更多信息,包括支持哪些测试及其工作方式,您必须查看 上的帮助test。当您运行该命令时help test,您将获得一个详细列表。这里不是复制所有内容,而是关于字符串运算符的部分:

      -z STRING      True if string is empty.

      -n STRING
         STRING      True if string is not empty.

      STRING1 = STRING2
                     True if the strings are equal.
      STRING1 != STRING2
                     True if the strings are not equal.
      STRING1 < STRING2
                     True if STRING1 sorts before STRING2 lexicographically.
      STRING1 > STRING2
                     True if STRING1 sorts after STRING2 lexicographically.
Run Code Online (Sandbox Code Playgroud)

请注意,-n STRING只是STRING做同样的事情:他们测试字符串STRING是否为空。

  • 我认为您错过了它的原因并且必须是这样的:如果不是,`[“$var”]`将永远无法用作测试,因为`$var`可能会扩展为`-n`。 (3认同)
  • 很好的解释 (2认同)

Ign*_*ams 15

[如果没有操作数,即使xx开头,x]也等价于[ -nx]-

$ [ -o ] ; echo $?
0
$ [ -eq ] ; echo $?
0
$ [ -n -o ] ; echo $?
0
$ [ -n -eq ] ; echo $?
0
Run Code Online (Sandbox Code Playgroud)

  • 请注意,从历史上看,`[ -t ]` 是在测试 stdout 是否是一个终端(`[ -t 1 ]` 的缩写)并且一些 shell 仍在这样做(在 `ksh93` 的情况下,只有当 `-t`是文字),因此使用 `[ -n "$var" ]` 比使用 `[ "$var" ]` 更好。尽管在一些旧的 `test` 实现中,对于 `$var` 的值,比如 `=`,这仍然会失败,在这种情况下,`[ "" != "$var" ]` 或 `[ "x$var" != x ]` 或 `case $x in "")...` 可能更好。 (4认同)
  • 这里有趣的`-o`选择。在像`bash`这样的一些shell中,`-o`既是一元(测试是否设置了一个选项)和二元(或)运算符,所以像`[ ! -o monitor ]` 不明确。是否在测试 `monitor` 选项未设置,或者 `!` 或 `monitor` 是非空字符串?POSIX 规则决定:后者(与 `[[ ! -o monitor ]]` 不同)。 (3认同)

gle*_*man 13

[ -n ]是真的,因为[命令(又名test命令)根据给定的参数数量起作用。如果只给出一个参数,如果参数是非空字符串,则结果为“真”。"-n" 是一个有 2 个字符的字符串,不是空的,因此是 "true"。