检查环境变量


74

我正在尝试检查环境变量的值,并根据该值执行某些操作,并且只要设置了该变量,它就可以正常工作。如果不是这样,我会遇到很多错误(我猜是BASH试图将我指定的字符串与未定义的变量进行比较)

我尝试执行额外的检查以防止它发生,但是没有运气。我正在使用的代码块是:

#!/bin/bash

if [ -n $TESTVAR ]
then
  if [ $TESTVAR == "x" ]
  then
    echo "foo"
    exit
  elif [ $TESTVAR == "y" ]
  then
    echo "bar"
    exit
  else
    echo "baz"
    exit
  fi
else
  echo -e "TESTVAR not set\n"
fi

这是输出:

$ export TESTVAR=x
$ ./testenv.sh 
foo
$ export TESTVAR=y
$ ./testenv.sh 
bar
$ export TESTVAR=q
$ ./testenv.sh 
baz
$ unset TESTVAR
$ ./testenv.sh 
./testenv.sh: line 5: [: ==: unary operator expected
./testenv.sh: line 9: [: ==: unary operator expected
baz

我的问题是,是否不应该将“ unset TESTVAR”取消?似乎并非如此...

Answers:


142

将变量括在双引号中。

if [ "$TESTVAR" = "foo" ]

如果您这样做并且变量为空,则测试将扩展为:

if [ "" = "foo" ]

而如果您不引用它,它将扩展为:

if [  = "foo" ]

这是语法错误。


无需将字符串文字(foo)放在引号中。
camh 2010年

34
@camh除良好实践,清晰性和真实文字可能包含空格外,没有其他内容。

4
我认为这可以解释为什么人们放弃了bash之类的东西,而创建了类似Perl之类的环境,或者为devops创建了类似PHP或python之类的环境。太多小细节无法在后面咬住你……
Felipe Valdes

9

查看标题为“参数扩展”的部分,您将发现:

$ {parameter:-word}
使用默认值。如果未设置parameter或为null,则替换word的扩展。否则,将替换参数的值。


很有意思,不知道有这样的事情存在。谢谢你的评论。
Hamza 2010年

7

在Bash(以及ksh和zsh)中,如果使用双方括号,则无需引用变量以防止变量为null或未设置。

$ if [ $xyzzy == "x" ]; then echo "True"; else echo "False"; fi
-bash: [: ==: unary operator expected
False
$ if [[ $xyzzy == "x" ]]; then echo "True"; else echo "False"; fi
False

还有其他优点


1
它们的缺点是脚本不再与Bourne Shell兼容-在这种情况下,这当然可能无关紧要。

1
@Neil:如果Bourne兼容性是一个问题,那么shebang应该说#!/bin/sh
丹尼斯·威廉姆森

7

您的测试以查看是否设置了该值

if [ -n $TESTVAR ]

实际上只是测试以查看该值是否设置为非空字符串。观察:

$ unset asdf
$ [ -n $asdf ]; echo $?
0
$ [ -n "" ]; echo $?
1
$ [ -n "asdf" ]; echo $?
0

请记住,这0表示真实。

如果您不需要与原始的Bourne外壳兼容,则可以将该初始比较更改为

if [[ $TESTVAR ]]

有没有一种方法可以测试$ asdf不为null并将其设置为与空字符串不同的东西,但是与原始Bourne shell兼容?
knocte

3

在解释了缺失之后,TESTVAR您正在评估[ == "y" ]。尝试以下任何一种:

 "$TESTVAR"
 X$TESTVAR == Xy
 ${TESTVAR:-''}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.