我有一些Unix shell脚本,在我开始做事情之前,我需要检查某些环境变量是否被设置,所以我做这样的事情:

if [ -z "$STATE" ]; then
    echo "Need to set STATE"
    exit 1
fi  

if [ -z "$DEST" ]; then
    echo "Need to set DEST"
    exit 1
fi

这需要大量的打字。是否有更优雅的习惯用法来检查是否设置了一组环境变量?

编辑:我应该提到的是,这些变量没有任何有意义的默认值-如果没有设置,脚本应该出错。


当前回答

Bash 4.2引入了-v操作符,用于测试名称是否被设置为任何值,甚至是空字符串。

$ unset a
$ b=
$ c=
$ [[ -v a ]] && echo "a is set"
$ [[ -v b ]] && echo "b is set"
b is set
$ [[ -v c ]] && echo "c is set"
c is set

其他回答

我总是用:

if [ "x$STATE" == "x" ]; then echo "Need to set State"; exit 1; fi

恐怕也没那么简洁。

在CSH下有$?STATE。

而不是使用外部shell脚本,我倾向于在登录shell中加载函数。我使用类似这样的辅助函数来检查环境变量,而不是任何设置变量:

is_this_an_env_variable ()
    local var="$1"
    if env |grep -q "^$var"; then
       return 0
    else
       return 1
    fi
 }

当然,最简单的方法是在shebang(脚本顶部的行)中添加-u开关,假设你使用的是bash:

# !/ bin / sh -

这将导致脚本退出,如果任何未绑定的变量潜伏在里面。

试试这个:

[ -z "$STATE" ] && echo "Need to set STATE" && exit 1;

我们可以写一个很好的断言来一次检查一堆变量:

#
# assert if variables are set (to a non-empty string)
# if any variable is not set, exit 1 (when -f option is set) or return 1 otherwise
#
# Usage: assert_var_not_null [-f] variable ...
#
function assert_var_not_null() {
  local fatal var num_null=0
  [[ "$1" = "-f" ]] && { shift; fatal=1; }
  for var in "$@"; do
    [[ -z "${!var}" ]] &&
      printf '%s\n' "Variable '$var' not set" >&2 &&
      ((num_null++))
  done

  if ((num_null > 0)); then
    [[ "$fatal" ]] && exit 1
    return 1
  fi
  return 0
}

示例调用:

one=1 two=2
assert_var_not_null one two
echo test 1: return_code=$?
assert_var_not_null one two three
echo test 2: return_code=$?
assert_var_not_null -f one two three
echo test 3: return_code=$? # this code shouldn't execute

输出:

test 1: return_code=0
Variable 'three' not set
test 2: return_code=1
Variable 'three' not set

更多这样的断言在这里:https://github.com/codeforester/base/blob/master/lib/assertions.sh