为什么 ${#}、${##} 为 1,${?}、${??} 和 ${!} 为 0,${-} 为 569JNORXZghiklms

为什么 ${#}、${##} 为 1,${?}、${??} 和 ${!} 为 0,${-} 为 569JNORXZghiklms

我找到了以下内容,想知道在哪里可以找到该手册:

❯ echo ${#}
1

❯ echo ${##}
1

❯ echo ${?}
0

❯ echo ${??}
0

❯ echo ${!}
0

❯ echo ${-}
569JNORXZghiklms

❯ echo ${--}
569JNORXZghiklms

答案1

大约有两个不同的地方,至少在 Bash 手册中是这样。这些应该是标准功能,并且在每个 shell 中都是相似的,即使${-}这里的实际值看起来像是来自 Zsh。

$ echo ${#}
1
$ echo ${?}
0
$ echo ${!}
0
$ echo ${-}
569JNORXZghiklms

这些是特殊参数 #?!-, 使用可选的大括号进行扩展。使用$#$?$!$-是相同的。还有一些其他特殊参数,以单个非字母非数字字符作为其“名称”,一般来说,${foo}与 相同,$foo但在类似 的情况下需要大括号${foo}bar,因为$foobar将被视为${foobar}

尤其,

  • $#是脚本或当前函数的位置参数或参数的数量。尝试fun() { echo $#; }; fun a b c;

  • $?是最后一个前台命令或管道的退出状态 ( ls -l /doesnotexist; echo $?)。

  • $!如果是最新的后台作业,则为进程 ID ( sleep 2 & ps uax |grep $!),并且

  • $-的清单set旗帜有效。 (setoptZsh 中的一些标志。Zsh 似乎也给出$!好像0没有这样的工作,Bash 将其显示为未设置。)

$ echo ${##}
1
$ echo ${??}
0
$ echo ${--}
569JNORXZghiklms

这些是特殊参数#?-,但还有附加参数参数扩展包括操作。 (我不知道该怎么称呼它们,它们只是参数扩展的一部分。)

  • ${#parameter}是值的长度范围,所以当$#is 1(或0等)时,${##}1,并且当 是 时foo=abc${#foo}3

    (有点相关,${parameter#word}删除前缀,它将是范围与引导部分匹配单词已删除(例如foo=abcdef; echo ${foo#??}给出cdef,因为?匹配任何一个字符)。的特殊情况${##}可以解释为获取长度或删除空前缀,但这里长度扩展胜过。${parameter%word}是相同的,但它删除了尾随部分。)

  • ${parameter?word}是一个“检查是否设置”扩展,它给出的值范围如果已设置,否则将引发错误,并显示以下给出的文本单词$?总是被设置的,所以检查不会做太多事情,但是尝试一下unset foo; echo ${foo?unset value\!}

  • ${parameter-word}是一个“默认值”扩展,它的值为范围如果已设置,否则单词$-总是被设置的,所以你得到它所具有的值。但如果foo未设置,${foo-bar}则为bar.

最后两个和其他类似的都有带有冒号和 的变体${parameter:?word}${parameter:?word}它们也会在以下情况下触发范围设置为空字符串。 Bash 的手册在这里可能更清楚,它提到了文本中的差异,但没有列出不带冒号的形式。这POSIX 文本有一个很好的表格, 尽管。


事实上#, ,?-在这里有两种不同的含义只是一个巧合,或者是具有有限的特殊字符集并且 shell 使用相当简洁的语法的结果。

相关内容