且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

测试在bash非零长度字符串:[-n" $ VAR" ]或[" $ VAR" ]

更新时间:2023-02-15 19:31:39

编辑:这是显示的 [$之间有更多的差异更完整版C $ C> (又名测试)和 [

下表显示了一个变量是否被引用与否,不管你使用单或双支架和变量是否只包含一个空间是影响事物是否使用测试带或不带 - N / -z 适合用于检查的变量。

  1A 2A 3A 4A 5A 6A | 1B 2B 3B 4B 6B 5B
       [[[-n [-n[-z [-z| [[[[[[-n [[-n[[-z [[-z
取消设置:虚假真假真真|虚假假假真真
空:虚假真假真真|虚假假假真真
空间:假的真真真真假|真真真真虚假
零:真真真真虚假|真真真真虚假
数字:真真真真虚假|真真真真虚假
焦炭:真的真的真的真的假假|真真真真虚假
hyphn:真的真的真的真的假假|真真真真虚假
二:|真真真真虚假-err-真-err-假-err-真
部分:|真真真真虚假-err-真-err-假-err-真
TSTR:真真真-err-假-err- |真真真真虚假
Fsym:真的假的真-err-假-err- |真真真真虚假
T =:真真真-err-假-err- |真真真真虚假
F =:假假真真真-err-假-err- |真真真真虚假
!T =:真真真-err-假-err- |真真真真虚假
F =:假假真真真-err-假-err- |真真真真假假的!
TEQ:|真真真真假假真真-err-假-err-真
FEQ:真的假的真-err-假-err- |真真真真虚假
TNE:真真真-err-假-err- |真真真真虚假
FNE:真的假的真-err-假-err- |真真真真虚假

如果你想知道如果一个变量是非零长度,请执行以下操作:


  • 报价单括号中的变量(列2A)

  • 使用 -n 并引述单括号中的变量(塔4a)

  • 使用双括号有或无带或不带 -n (列1B - 4B)报价

在列1a通知开始标记行两化的结果表明, [正在评估的变量,如果的的内容的他们是有条件的前pression的一部分(该结果由T或F,在说明栏中所隐含的断言匹配)。当 [用于(列1B),该变量的内容被看作是一个字符串,而不是评估。

列3a和5a中的错误的事实,变量值包括空间和变量是无引号引起的。再次,如图列3b和5b中, [[评估变量的内容为字符串。

如果你使用 [,关键要确保你没有得到意外的结果是引用变量。使用 [,也没关系。

错误消息,目前正在燮pressed,是一元运算符预期或二元运算符预期。

这是产生上表中的脚本。

 #!/斌/庆典
#由丹尼斯·威廉姆森
#2010-10-06修订2010-11-10
#为http://***.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var
#设计,以适应一个80字符终端DW = 5#描述列宽
W = 6#表格列宽T(){printf的% - $ {白}的真; }
f()的{[[$? == 1]]&放大器;&安培; printf的% - $ {白}的假|| printf的% - $ {白}的-e​​rr- }O =的/ dev / null的回声1A 2A 3A 4A 5A 6A | 1B 2B 3B 4B 5B 6B
回声[[[-n [-n[-z [-z| [[[[[[-n [[-n[[-z [[-z'而阅读-rðŤ

    printf的% - $ {DW}等:$ D    案例$ d。在
        未设置)未设置牛逼;;
        空间)T ='';;
    ESAC    [$ T] 2 - ; $的O&&安培; Ť|| F
    [$ T]放;&安培; Ť|| F
    [-n $ T] 2 - ; $的O&&安培; Ť|| F
    [-n$ T]放;&安培; Ť|| F
    [-z $ T] 2 - ; $的O&&安培; Ť|| F
    [-z$ T]放;&安培; Ť|| F
    呼应-n|
    [[$ T]]&放大器;&安培; Ť|| F
    [[$ T]]&放大器;&安培; Ť|| F
    [[-n $ T]]&放大器;&安培; Ť|| F
    [-n$ T]]&放大器;&安培; Ť|| F
    [[-z $ T]]&放大器;&安培; Ť|| F
    [[-z$ T]]&放大器;&安培; Ť|| F
    回声完成<<'EOF'
未设置
空值
空间
零0
数字1
焦炭ç
hyphn -z
2 A B
一部分-a
TSTR -n一
Fsym -h。
T = 1 = 1
F = 1 = 2
牛逼!= 1!= 2
˚F!= 1!= 1
TEQ 1 -eq 1
FEQ 1 -eq 2
TNE 1 -ne 2
FNE 1 -ne 1
EOF

I've seen bash scripts test for non-zero length string two different ways. Most scripts use the -n option:

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

But the -n option isn't really needed:

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

Which is the better way?

Similarly, which is the better way for testing for zero-length:

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

or

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

Edit: This is a more complete version that shows more differences between [ (aka test) and [[.

The following table shows that whether a variable is quoted or not, whether you use single or double brackets and whether the variable contains only a space are the things that affect whether using a test with or without -n/-z is suitable for checking a variable.

       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

If you want to know if a variable is non-zero length, do any of the following:

  • quote the variable in single brackets (column 2a)
  • use -n and quote the variable in single brackets (column 4a)
  • use double brackets with or without quoting and with or without -n (columns 1b - 4b)

Notice in column 1a starting at the row labeled "two" that the result indicates that [ is evaluating the contents of the variable as if they were part of the conditional expression (the result matches the assertion implied by the "T" or "F" in the description column). When [[ is used (column 1b), the variable content is seen as a string and not evaluated.

The errors in columns 3a and 5a are caused by the fact that the variable value includes a space and the variable is unquoted. Again, as shown in columns 3b and 5b, [[ evaluates the variable's contents as a string.

If you're using [, the key to making sure that you don't get unexpected results is quoting the variable. Using [[, it doesn't matter.

The error messages, which are being suppressed, are "unary operator expected" or "binary operator expected".

This is the script that produced the table above.

#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://***.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