我听说建议我这样做
if [ "x$variable" = "x" ]
是否正确道路? (必须有些更简单的方法)
#1 楼
如果未设置或将变量设置为空字符串(“”),则返回true。if [ -z "${VAR}" ];
评论
这是否包括变量IS SET的值是否为“”?
–布伦特
09年5月12日在18:25
是的,它确实...“ -z”测试零长度的字符串。
– David Z
09年5月13日在2:40
如果[! -z“ $ VAR”];
–亚伦·科普利
13年7月22日在17:26
如果[-n“ $ VAR”],则-z的倒数为-n;
–Felipe Alvarez
13-10-9在5:59
双引号确保变量不会拆分。命令行上的简单$ var将由空格分隔为参数列表,而“ $ var”始终仅是一个参数。经常给变量加引号是一种好习惯,它可以阻止您跳入包含空格的文件名(除其他外)。示例:执行a =“ x --help”之后,尝试使用cat $ a-它会为您提供cat的帮助页面。然后尝试使用cat“ $ a”-(通常)说cat:x --help:没有这样的文件或目录。简而言之,尽早报价并经常报价,您几乎永远不会后悔。
–Score_Under
2014年7月15日13:40
#2 楼
在Bash中,当您不关心不支持它的shell的可移植性时,应始终使用双括号语法:以下任意一种:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
在Bash中,使用双方括号不需要引号。您可以简化包含以下值的变量的测试:
if [[ $variable ]]
此语法与ksh兼容(无论如何至少与ksh93兼容)。在纯POSIX或更旧的Bourne外壳(如sh或破折号)中不起作用。
有关双方括号和单方括号之间差异的更多信息,请参见此处和BashFAQ / 031。
您可以测试变量是否未明确设置(与空字符串不同):
if [[ -z ${variable+x} ]]
其中的“ x”是任意的。 br />
如果您想知道变量是否为空但未设置,请执行以下操作:
if [[ -z $variable && ${variable+x} ]]
评论
如果[[$ variable]]对我来说很好用,甚至不需要其他提议的解决方案之一所需要的set -u。
– Teemu Leisti
2012年9月14日15:14
我认为这比公认的答案更好。
– q
13年4月5日在10:00
为什么在建议使用非便携式功能时没有好处呢?
–阿拉斯泰尔·欧文(Alastair Irvine)
2014年11月24日上午8:16
@AlastairIrvine:我在回答的第一句话中提到了可移植性,问题标题和正文中包含“ Bash”一词,问题被标记为bash,双括号结构在许多方面都具有明显的优势。而且出于一致性和可维护性的原因,我不建议混合使用括号样式。如果您需要最大,最低的公分母可移植性,请使用sh代替Bash。如果您需要它提供的增强功能,请使用Bash并充分使用它。
–丹尼斯·威廉姆森
2014年11月24日13:59
@BrunoBronosky:我还原了编辑。不需要;在最后。然后可以在下一行完全不使用分号。
–丹尼斯·威廉姆森
16-11-30在23:52
#3 楼
bash(和任何POSIX兼容的shell)中的变量可以处于以下三种状态之一:unset
设置为空字符串
设置为非字符串-空字符串
大多数时候,您只需要知道变量是否设置为非空字符串,但是偶尔区分未设置和设置为空字符串很重要。
以下是如何测试各种可能性的示例,它可以在bash或任何POSIX兼容的shell中运行:
if [ -z "${VAR}" ]; then
echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
echo "VAR is either unset or set to a non-empty string"
fi
同样的东西,但是以方便的表格形式出现:
+-------+-------+-----------+
VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ] | true | true | false |
| [ -z "${VAR+set}" ] | true | false | false |
| [ -z "${VAR-unset}" ] | false | true | false |
| [ -n "${VAR}" ] | false | false | true |
| [ -n "${VAR+set}" ] | false | true | true |
| [ -n "${VAR-unset}" ] | true | false | true |
+-----------------------+-------+-------+-----------+
${VAR+foo}
构造扩展为空字符串如果未设置VAR
,或者如果foo
设置为任何值(包括空字符串),则设置为VAR
。${VAR-foo}
构造函数扩展为VAR
的值(包括设置为空字符串),并扩展为foo
未设定。这对于提供用户可覆盖的默认值很有用(例如,除非变量${COLOR-red}
设置为q43,否则red
表示要使用COLOR
)。通常建议使用
[ x"${VAR}" = x ]
来测试变量是否为未设置或设置为空字符串是因为[
命令(也称为test
)的某些实现存在错误。如果将VAR
设置为类似-n
,则某些实现在给定[ "${VAR}" = "" ]
时会做错事情,因为[
的第一个参数被错误地解释为-n
运算符,而不是字符串。评论
也可以使用[-z“ $ {VAR-set}”]来测试设置为空字符串的变量。
–nwellnhof
13年5月17日在17:56
@nwellnhof:谢谢!我更新了答案,以使用更简短的语法。
–理查德·汉森(Richard Hansen)
13年5月18日在18:00
第一个和最后一个构造有什么区别?它们都对应于“ VAR未设置或设置为非空字符串”。
– Faheem Mitha
13年7月22日在8:53
@FaheemMitha:这不是你的错-我的答案很难看。我添加了一个表格,希望可以使答案更加清楚。
–理查德·汉森(Richard Hansen)
13年7月22日在17:10
未设置的检查不可靠。如果用户在bash中调用set -u或set -o名词集,则测试将仅导致错误“ bash:VAR:未绑定变量”。有关更可靠的未设置检查,请参见stackoverflow.com/a/13864829。我的检查变量是否为null或未设置是[-z“ $ {VAR:-}”]。我检查变量是否为非空为[“ $ {VAR:-}”]。
–金凯文
17年9月14日在14:12
#4 楼
-z
是最好的方法。我使用的另一个选项是设置变量,但是它可以被另一个变量覆盖,例如
export PORT=${MY_PORT:-5432}
如果
$MY_PORT
变量为空,则将PORT
设置为5432,否则将PORT设置为MY_PORT
的值。请注意,语法包括冒号和破折号。评论
今天偶然发现了这个,这正是我想要的。谢谢!在某些脚本中,我必须容忍set -o nounset。
–opello
2012-02-16 23:58
#5 楼
如果您有兴趣区分空置状态和未设置状态,请查看bash的-u选项:$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR
$ [ -z "$BAR" ] && echo true
true
#6 楼
我见过[ -z "$foo" ]
的另一种替代方法,但是我不确定为什么人们会使用这种方法,有人知道吗?[ "x${foo}" = "x" ]
无论如何,如果您不允许取消设置变量(通过
set -u
或set -o nounset
),那么这两种方法都会遇到麻烦。有一个简单的解决方法:[ -z "${foo:-}" ]
注意:这将使您的变量未定义。
评论
在pubs.opengroup.org/onlinepubs/009695399/utilities/test.html上有关于-z替代项的评论。基本上,它并不打算替代-z。相反,它处理$ foo可以扩展为以[或测试引起混淆的元字符]开头的情况。在开始时放置任意的非元字符可以消除这种可能性。
–詹姆斯·斯诺格(James Sneeringer)
2011年12月9日19:15
#7 楼
该问题询问如何检查变量是否为空字符串,并且已经给出了最佳答案。但是经过一段时间的php编程后,我进入了这里,而我实际上搜索的是像空一样的检查在bash外壳中工作的php中的函数。
读完答案后,我意识到我在bash中的想法不正确,但是无论如何,在那时,像php中的empty这样的函数在我的bash代码中会非常方便。 />由于我认为这可能会发生在其他人身上,因此我决定在bash中转换php empty函数。
根据php手册:如果变量不存在或者其值是以下:
“”“(空字符串)
0(0为整数)
0.0(0为浮点数)
” 0“ (0作为字符串)
空数组
声明的变量,但没有值
当然,null和false情况不能在bash中转换,因此将其省略。
function empty
{
local var=""
# Return true if:
# 1. var is a null string ("" as empty string)
# 2. a non set variable is passed
# 3. a declared variable or array but without a value is passed
# 4. an empty array is passed
if test -z "$var"
then
[[ $( echo "1" ) ]]
return
# Return true if var is zero (0 as an integer or "0" as a string)
elif [ "$var" == 0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
# Return true if var is 0.0 (0 as a float)
elif [ "$var" == 0.0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
fi
[[ $( echo "" ) ]]
}
用法示例:
if empty "${var}"
then
echo "empty"
else
echo "not empty"
fi
演示:
以下代码段:
#!/bin/bash
vars=(
""
0
0.0
"0"
1
"string"
" "
)
for (( i=0; i<${#vars[@]}; i++ ))
do
var="${vars[$i]}"
if empty "${var}"
then
what="empty"
else
what="not empty"
fi
echo "VAR \"$var\" is $what"
done
exit
输出:
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
在bash逻辑中已经说过在此功能中对零进行检查会导致副作用,恕我直言,使用此功能的任何人都应评估这种风险,并可能决定取消那些检查,只保留第一个检查。
评论
在函数里面为空-为什么写[[$(echo“ 1”)]];返回,而不是简单地返回1?
–多尔
16-09-28在19:33
#8 楼
整个if-then和-z都是不必要的。[ "$foo" ] && echo "foo is not empty" [ "$foo" ] || echo "foo is indeed empty"
评论
如果foo只包含空格,那将失败
–布赖恩
2010年5月20日在21:16
如果foo以破折号开头,则在某些shell中也会失败,因为foo被解释为选项。例如。在solaris ksh上,zsh和bash没问题,sh和/ bin / test将失败
–ktf
2011年10月20日在7:40
#9 楼
我的5美分:还有比if ...
短的语法,这是这样的:VALUE="${1?"Usage: q4312078q value"}"
如果提供了参数,则此行将设置VALUE,并且将显示错误消息
可以在abs指南中找到另一个示例(搜索«Example 10-7»)。 br />
#10 楼
确实在$ FOO设置为空时正确:[ "${FOO+x}" = x ] && [ -z "$FOO" ]
#11 楼
个人更喜欢更清晰的检查方法:if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
评论
一些外壳不接受双等号。
–丹尼斯·威廉姆森
2012年2月25日在12:19
问题是关于bash。我正在使用bash。对我来说效果很好。您到底在说什么?
– Fedir RYKHTIK
2012-2-25在13:03
如果您使用的是Bash,则应使用双方括号。对于那些可能阅读您的答案并使用其他Shell的人,我之前的评论是一个简单的事实陈述。
–丹尼斯·威廉姆森
2012年2月25日15:49
在这种情况下,可以使用单个方括号,请参阅serverfault.com/questions/52034/…
–卢卡·鲍里昂(Luca Borrione)
2012年8月31日19:21
#12 楼
duffbeer703解决方案的oneliner扩展:#! /bin/bash
[ -z "" ] || some_command_that_needs__parameter
#13 楼
没有确切的答案,但是遇到了这个窍门。如果您要查找的字符串来自“命令”,那么您实际上可以将命令存储在环境中。变量,然后每次对if语句执行一次,则不需要括号!例如,该命令确定您是否使用debian:
grep debian /proc/version
完整示例:
IS_DEBIAN="grep -i debian /proc/version"
if $IS_DEBIAN; then
echo 'yes debian'
else
echo 'non debian'
fi
所以这就像一种间接方法(每次都运行它)来检查一个空字符串(它恰好正在检查命令的错误响应,但是它也恰好返回一个空字符串)字符串)。
评论
请参阅:在StackOverflow上的Bash中测试非零长度的字符串。在Bash中,[[-v VAR]]用于检查是否定义了VAR,[[-z $ VAR]]用于检查是否将“ $ VAR”扩展为空字符串(“”)。因此,您可以使用[[-v VAR && -z $ VAR]]。在此处阅读更多信息(带有官方参考)