我见过Bash脚本用两种不同的方式测试长度为非零的字符串。大多数脚本使用-n选项:

#!/bin/bash
# With the -n option
if [ -n "$var" ]; then
  # Do something when var is non-zero length
fi

但是-n选项其实并不需要:

# Without the -n option
if [ "$var" ]; then
  # Do something when var is non-zero length
fi

哪一种方法更好?

类似地,哪种是测试零长度的更好方法:

if [ -z "$var" ]; then
  # Do something when var is zero-length
fi

or

if [ ! "$var" ]; then
  # Do something when var is zero-length
fi

当前回答

就Bash而言,最好使用更强大的[[。

通常情况下

if [[ $var ]]; then   # var is set and it is not empty
if [[ ! $var ]]; then # var is not set or it is set to an empty string

上面两个结构看起来干净且可读。在大多数情况下,它们应该足够了。

请注意,我们不需要在[[]内部引用变量展开,因为没有词分裂和通配符的危险。

防止shellcheck的软投诉[[$var]]和[[!$var]],我们可以使用-n选项。

极少数情况下

在极少数情况下,我们必须区分“被设置为空字符串”和“根本不被设置”,我们可以使用这些:

if [[ ${var+x} ]]; then           # var is set but it could be empty
if [[ ! ${var+x} ]]; then         # var is not set
if [[ ${var+x} && ! $var ]]; then # var is set and is empty

我们也可以用-v检验:

if [[ -v var ]]; then             # var is set but it could be empty
if [[ ! -v var ]]; then           # var is not set
if [[ -v var && ! $var ]]; then   # var is set and is empty
if [[ -v var && -z $var ]]; then  # var is set and is empty

相关职位和文件

有很多与此相关的帖子。以下是一些例子:

如何检查一个变量是否设置在Bash? 如何检查环境变量是否存在并获取其值? 如何在Bash中找到变量是否为空 “加号”(“+:”)在shell脚本表达式中是什么意思? 在Bash中,双方括号[[]]比单方括号[]更可取吗? Bash中单方括号和双方括号的区别是什么? mklement0给出了一个很好的回答,他谈到了[[vs [] Bash Hackers Wiki - [vs []

其他回答

这里还有一些测试

如果string不为空,则为True:

[ -n "$var" ]
[[ -n $var ]]
test -n "$var"
[ "$var" ]
[[ $var ]]
(( ${#var} ))
let ${#var}
test "$var"

string为空时为True:

[ -z "$var" ]
[[ -z $var ]]
test -z "$var"
! [ "$var" ]
! [[ $var ]]
! (( ${#var} ))
! let ${#var}
! test "$var"

用例/esac测试:

case "$var" in
  "") echo "zero length";;
esac

不幸的是,我还没有找到为什么有两种语法放在首位。两者似乎都是在1979年Unix版本7中同时引入的。

1994年的单一Unix规范首选-n和-z语法。从那以后,同样的建议被逐字复制到POSIX的每个版本中,包括最新版本POSIX.1-2017:

这两条命令: 测试" $ 1 " 测试!" $ 1 " 不能在某些历史系统上可靠地使用。意想不到的 如果使用这样的字符串表达式并且$1 扩展为'!', '(',或已知的一元主元。更好的构念是: Test -n "$1" Test -z "$1" 分别。

我认为,如果你想学而不实地遵循规范中的每一条建议,那么你应该继续使用-n和-z,但说真的,你需要兼容超过28年的系统吗?

在我看来,if ["$var"]和if [!"$var"]使得该语法成为明显的赢家。但底线是没有功能上的区别,所以随你的个人喜好去吧。

正确答案如下:

if [[ -n $var ]] ; then
  blah
fi

注意[[…]]],它正确地处理变量的引用。

计算空环境变量的另一种可能更透明的方法是使用…

  if [ "x$ENV_VARIABLE" != "x" ] ; then
      echo 'ENV_VARIABLE contains something'
  fi