我有一个数组,当我的脚本运行时,它会填充不同的错误消息。
我需要一种方法来检查脚本末尾是否为空,如果是,则采取特定操作。
我已经尝试将其视为普通 VAR 并使用 -z 进行检查,但这似乎不起作用。有没有办法在 Bash 中检查数组是否为空?
Mic*_*ton 211
假设您的数组是$errors,只需检查元素数是否为零。
if [ ${#errors[@]} -eq 0 ]; then
echo "No errors, hooray"
else
echo "Oops, something went wrong..."
fi
Run Code Online (Sandbox Code Playgroud)
x-y*_*uri 39
在这种情况下,我通常使用算术展开:
if (( ${#a[@]} )); then
echo not empty
fi
Run Code Online (Sandbox Code Playgroud)
wge*_*get 11
您也可以将数组视为一个简单的变量。这样,只需使用
if [ -z "$array" ]; then
echo "Array empty"
else
echo "Array non empty"
fi
Run Code Online (Sandbox Code Playgroud)
或使用另一边
if [ -n "$array" ]; then
echo "Array non empty"
else
echo "Array empty"
fi
Run Code Online (Sandbox Code Playgroud)
与解决方案的问题是,如果一个数组声明如下:array=('' foo)。这些检查会将数组报告为空,而显然不是。(感谢@musiphil!)
使用[ -z "$array[@]" ]显然也不是解决方案。不指定大括号试图解释$array为字符串([@]在这种情况下是一个简单的文字字符串),因此总是报告为 false:“文字字符串是否为[@]空?” 显然不是。
我检查了它bash-4.4.0:
#!/usr/bin/env bash
set -eu
check() {
if [[ ${array[@]} ]]; then
echo not empty
else
echo empty
fi
}
check # empty
array=(a b c d)
check # not empty
array=()
check # empty
Run Code Online (Sandbox Code Playgroud)
和bash-4.1.5:
#!/usr/bin/env bash
set -eu
check() {
if [[ ${array[@]:+${array[@]}} ]]; then
echo non-empty
else
echo empty
fi
}
check # empty
array=(a b c d)
check # not empty
array=()
check # empty
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,您需要以下构造:
${array[@]:+${array[@]}}
Run Code Online (Sandbox Code Playgroud)
因为它不会在空或未设置的数组上失败。那就是如果你set -eu像我通常那样做。这提供了更严格的错误检查。从文档:
-e
如果管道(请参阅管道)(可能由单个简单命令(请参阅简单命令)、列表(请参阅列表)或复合命令(请参阅复合命令)组成)返回非零状态,则立即退出。如果失败的命令是紧跟在 while 或 until 关键字之后的命令列表的一部分、if 语句中测试的一部分、在 && 或 || 中执行的任何命令的一部分,则 shell 不会退出 列表除了最后一个 && 或 || 之后的命令,管道中除最后一个之外的任何命令,或者如果命令的返回状态正在用 ! 反转。如果子shell 以外的复合命令由于命令在-e 被忽略时失败而返回非零状态,则shell 不会退出。如果设置了 ERR 上的陷阱,则会在 shell 退出之前执行。
该选项分别适用于shell环境和每个子shell环境(参见命令执行环境),并且可能导致子shell在执行子shell中的所有命令之前退出。
如果复合命令或 shell 函数在 -e 被忽略的上下文中执行,则复合命令或函数体内执行的任何命令都不会受到 -e 设置的影响,即使设置了 -e 并且命令返回故障状态。如果复合命令或 shell 函数在忽略 -e 的上下文中执行时设置了 -e,则在复合命令或包含函数调用的命令完成之前,该设置不会产生任何影响。
-u
执行参数扩展时,将未设置的变量和特殊参数 '@' 或 '*' 以外的参数视为错误。错误消息将写入标准错误,并且非交互式 shell 将退出。
如果您不需要它,请随意省略:+${array[@]}部分。
还要注意,[[在这里使用运算符是必不可少的,[你会得到:
$ cat 1.sh
#!/usr/bin/env bash
set -eu
array=(a b c d)
if [ "${array[@]}" ]; then
echo non-empty
else
echo empty
fi
$ ./1.sh
_/1.sh: line 4: [: too many arguments
empty
Run Code Online (Sandbox Code Playgroud)