Test for non-zero length string in Bash: [ -n “$var” ] or [ “$var” ]
我见过用两种不同的方法测试非零长度字符串的bash脚本。大多数脚本使用-n选项:
1 2 3 4 5 | #!/bin/bash # With the -n option if [ -n"$var" ]; then # Do something when var is non-zero length fi |
但是-n选项并不真正需要:
1 2 3 4 | # Without the -n option if ["$var" ]; then # Do something when var is non-zero length fi |
哪种方法更好?
同样,测试零长度的更好方法是:
1 2 3 | if [ -z"$var" ]; then # Do something when var is zero-length fi |
或
1 2 3 | if [ !"$var" ]; then # Do something when var is zero-length fi |
编辑:这是一个更完整的版本,显示了
下表显示了变量是否被引用、是否使用单括号或双括号以及变量是否只包含空格是影响使用带有或不带
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 1a 2a 3a 4a 5a 6a |1b 2b 3b 4b 5b 6b [ [" [-n [-n" [-z [-z" |[[ [[" [[-n [[-n" [[-z [[-z" unset: false false true false true true |false false false false true true null : false false true false true true |false false false false true true space: false true true true true false |true true true true false false zero : true true true true false false |true true true true false false digit: true true true true false false |true true true true false false char : true true true true false false |true true true true false false hyphn: true true true true false false |true true true true false false two : -err- true -err- true -err- false |true true true true false false part : -err- true -err- true -err- false |true true true true false false Tstr : true true -err- true -err- false |true true true true false false Fsym : false true -err- true -err- false |true true true true false false T= : true true -err- true -err- false |true true true true false false F= : false true -err- true -err- false |true true true true false false T!= : true true -err- true -err- false |true true true true false false F!= : false true -err- true -err- false |true true true true false false Teq : true true -err- true -err- false |true true true true false false Feq : false true -err- true -err- false |true true true true false false Tne : true true -err- true -err- false |true true true true false false Fne : false true -err- true -err- false |true true true true false false |
如果要知道变量的长度是否为非零,请执行以下任一操作:
- 引用单括号中的变量(第2a列)
- 使用
-n 并在单括号中引用变量(第4a列) - 使用带或不带引号的双括号,带或不带
-n (第1B-4B列)
注意,在第1a列中,从标记为"2"的行开始,结果表明
第3a列和第5a列中的错误是由于变量值包含空格且变量未被引用这一事实造成的。同样,如第3b和5b列所示,
如果您使用的是
被抑制的错误消息是"预期一元运算符"或"预期二元运算符"。
这是生成上表的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #!/bin/bash # by Dennis Williamson # 2010-10-06, revised 2010-11-10 # for http://stackoverflow.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var # designed to fit an 80 character terminal dw=5 # description column width w=6 # table column width t () { printf"%-${w}s""true"; } f () { [[ $? == 1 ]] && printf"%-${w}s""false" || printf"%-${w}s""-err-"; } o=/dev/null echo ' 1a 2a 3a 4a 5a 6a |1b 2b 3b 4b 5b 6b' echo ' [ [" [-n [-n" [-z [-z" |[[ [[" [[-n [[-n" [[-z [[-z"' while read -r d t do printf"%-${dw}s:""$d" case $d in unset) unset t ;; space) t=' ' ;; esac [ $t ] 2>$o && t || f ["$t" ] && t || f [ -n $t ] 2>$o && t || f [ -n"$t" ] && t || f [ -z $t ] 2>$o && t || f [ -z"$t" ] && t || f echo -n"|" [[ $t ]] && t || f [["$t" ]] && t || f [[ -n $t ]] && t || f [[ -n"$t" ]] && t || f [[ -z $t ]] && t || f [[ -z"$t" ]] && t || f echo done <<'EOF' unset null space zero 0 digit 1 char c hyphn -z two a b part a -a Tstr -n a Fsym -h . T= 1 = 1 F= 1 = 2 T!= 1 != 2 F!= 1 != 1 Teq 1 -eq 1 Feq 1 -eq 2 Tne 1 -ne 2 Fne 1 -ne 1 EOF |
就bash而言,最好使用更强大的
1 2 | 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对
在我们必须区分"设置为空字符串"和"根本不设置"的罕见情况下,我们可以使用这些:
1 2 3 | 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 |
我们也可以使用
1 2 3 4 | 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脚本表达式中,"+colon"("+:")是什么意思?
- 在bash中,双方括号[]比单方括号[]更可取吗?
- bash中的单方括号和双方括号有什么区别?
- Mklement0给出了一个很好的答案,他谈到了
[[ 对[ 。 - bash黑客wiki-
[ vs[[
这里还有一些测试
如果字符串不为空,则为true:
1 2 3 4 5 6 7 8 | [ -n"$var" ] [[ -n $var ]] test -n"$var" ["$var" ] [[ $var ]] (( ${#var} )) let ${#var} test"$var" |
如果字符串为空,则为true:
1 2 3 4 5 6 7 8 | [ -z"$var" ] [[ -z $var ]] test -z"$var" ! ["$var" ] ! [[ $var ]] ! (( ${#var} )) ! let ${#var} ! test"$var" |
使用
1 2 3 | case"$var" in "") echo"zero length";; esac |
评估空env变量的另一种更透明的方法是使用…
1 2 3 | if ["x$ENV_VARIABLE" !="x" ] ; then echo 'ENV_VARIABLE contains something' fi |
正确答案如下:
1 2 3 | if [[ -n $var ]] ; then blah fi |
注意