【问题标题】:logical OR existence test for shell variables under bashbash下shell变量的逻辑或存在测试
【发布时间】:2015-07-14 12:04:36
【问题描述】:

我需要根据 bash 下是否设置了 shell_var_1 OR shell_var_2 来执行一些逻辑。

如果我使用 #!/bin/sh,我可以使用:

if [ "$shell_var_1" -ne "0" -o "$shell_var_2" -ne "0" ] ; then
 logic
fi

这只是使用测试中的“-o”(http://unixhelp.ed.ac.uk/CGI/man-cgi?test

但是,如果我指定 #!/bin/bash,并想使用 '-v' 选项来测试 shell 变量的存在(从 bash 4.2 开始添加),我该怎么做呢?

参考:https://tiswww.case.edu/php/chet/bash/bash.html

if [ -v shell_var_1 -o -v shell_var_2 ] ; then
 logic
fi

^ 这被认为是正确的吗?我不是把 bash 和 test 算子混在一起了吗?

【问题讨论】:

  • 它适用于我(bash 4.3.33)。至于混合 bash 和测试运算符,我怀疑它是,因为括号运算符是内置的 bash(与一些旧系统不同,实际上有一个 /bin/[ 可执行文件,或指向 /bin/test 的符号链接)。如果您担心执行规范 bash,只需使用双括号和 || 逻辑 OR 运算符。顺便说一句,我的系统确实有/usr/bin/[,但type [ 表明[ 是一个shell 内置,这意味着除非你专门调用/usr/bin/[,否则你使用的是shell 内置而不是可执行文件。
  • 不要使用-o-a。它们在便携方面表现不佳。在[ ... ] 测试之间使用||&&[/test 目前都内置在 bash(和其他 shell)中,但外部二进制文件仍然存在于许多/大多数(/所有?)系统上。

标签: bash shell


【解决方案1】:
[[ $shell_var_1 || $shell_var_2 ]]

...在 bash 中编写它是一种非常简洁和惯用的方式,可与旧版本兼容,假设您认为设置为空值的变量不存在。


如果您想要一个可移植的替代方案,它将设置为零字节值的变量视为未设置,那么

[ -n "$shell_var_1" ] || [ -n "$shell_var_2" ]

...将投放。


如果您想要一个可移植的替代方案,将设置为空值的变量视为现有,那么

[ -n "${shell_var_1+set}" ] || [ -n "${shell_var_2+set}" ]

...会这样做。


如果您真的想使用-v(因此,将设置为空值的变量视为存在,但不必要地与 POSIX shell 和较旧的 bash 版本不兼容 - 包括 MacOS 附带的那些),然后使用 [[ ]] - - 这让读者清楚地知道您使用的是纯 bash 语法,并且不容易出现 test[(甚至它们的 bash 内置形式)容易出现的一些晦涩的错误以超过 2-arg 的形式使用:

[[ -v shell_var_1 || -v shell_var_2 ]]

【讨论】:

  • 谢谢!内联[ -v shell_var_1 -o -v shell_var_2 ] 确实有效的任何原因?
  • @OptimizedCoder,因为 [ 是由内置的 shell 提供的,除非您明确运行 /usr/bin/[command [ 来请求外部版本。
  • @OptimizedCoder, ...在这种情况下它容易出错的原因是test 的 POSIX 规范的应用说明部分中描述的问题适用于 any 实现test 规范,包括内置规范,而[[ 不符合该规范——尤其是通过拥有自己的解析器支持,从而能够明确地区分数据和语法.
  • ...好吧,任何经过深思熟虑且现在不鼓励使用 XSI 扩展的实现,就是这样。
猜你喜欢
  • 2014-05-12
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
  • 2021-06-28
相关资源
最近更新 更多