回答
我认为你的回答是暗示(如果没有说明)Vinko的answer,虽然它不是简单地拼写出来。为了区分VAR是否被设置,但空或没有设置,你可以使用:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
你也许可以在第二行的两个测试组合成一个具有:
if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
但是,如果你读Autoconf的文档,你会发现他们不建议将术语与'-a
'相结合,并建议使用单独的简单测试结合&&
。我没有遇到有问题的系统;这并不意味着他们过去并不存在(但他们现在可能非常罕见,即使它们在遥远的过去并不稀罕)。
您可以在Bash手册中找到这些的详细信息,以及其他相关的shell parameter expansions,test
or [
命令和conditional expressions。
我最近通过电子邮件询问这个答案与问题:
您使用两个测试,据我所知,第二个好,但不是第一个。更确切地说,我不明白是否需要进行可变扩展
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
难道这不会完成相同的工作吗?
if [ -z "${VAR}" ]; then echo VAR is not set at all; fi
公平问题 - 答案是:“不,你更简单的替代不会做同样的事情。”
想我测试之前写:
VAR=
您的测试会说:“VAR没有设置在所有”,但我会说(通过暗示,因为它呼应什么)“VAR设置,但其价值可能是空的“。尝试此脚本:
(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo JL:1 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:1 VAR is not set at all; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo JL:2 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:2 VAR is not set at all; fi
)
的输出是:
JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all
在第二对测试中,变量设置,但是它被设置为空值。这是${VAR=value}
和${VAR:=value}
表示法的区别。同上${VAR-value}
和${VAR:-value}
,和${VAR+value}
和${VAR:+value}
等等。
由于Gili在他answer指出,如果你与set -o nounset
选项运行bash
,那么上面的基本答案失败,unbound variable
。这是很容易纠正:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
或者,你可以取消set -o nounset
选项与set +u
(set -u
等同于set -o nounset
)。
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO=""
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO="a"
~> if [ -z $FOO ]; then echo "EMPTY"; fi
~>
-z也适用于未定义的变量。要区分未定义和已定义,您将使用列出的内容here或更清晰的说明here。
最干净的方式是使用像这些示例中的扩展。要获得所有选项,请检查手册的参数扩展部分。
替代字:
~$ unset FOO
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
~$ FOO=""
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
DEFINED
默认值:
~$ FOO=""
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
~$ unset FOO
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
UNDEFINED
当然你会使用其中的一个不同,把你想要的,而不是“默认值”的值,并使用扩张直接,如果适当的话。
但我想区分字符串是“”还是一直未定义。那可能吗? – SetJmp 2008-10-23 04:32:51
这个答案*确实*告诉如何区分这两种情况;按照它提供的bash faq链接进行更多讨论。 – 2008-10-23 04:45:07
我补充说,他的评论后,查尔斯 – 2008-10-23 04:52:50
调用不带任何参数设置..它输出定义的所有瓦尔..
名单上的最后的将是那些在脚本定义..
,所以你能管其输出的东西,可以计算出什么东西被定义和什么不是
高级bash脚本指南,10.2。参数换人:
- $ {变种+ blahblah}:如果变量被定义, 'blahblah' 为取代的 表达,否则返回null是取代
- $ {VAR-blahblah}:如果变量被定义它本身被替换,否则 'blahblah'被替换
- $ {var?blahblah}:如果var被定义,它将被替换,否则 函数存在'blahblah'作为错误消息。
立足于变量$ myStr中是否定义了你的程序逻辑或没有,你可以做到以下几点:
isdefined=0
${mystr+ export isdefined=1}
现在,如果isdefined = 0,则该变量undefined,如果isdefined = 1变量被定义为
这种检查变量的方式比上面的答案更好,因为它更优雅,更易读,而且如果你的bash shell被配置为出错使用未定义的变量(set -u)
,脚本将提前终止。
其他有用的东西:
有7默认值分配给$ myStr中,如果它是不确定的,并使其保持完好,否则:
mystr=${mystr- 7}
打印错误消息并在变量未定义时退出函数:
: ${mystr? not defined}
请注意,在这里我使用':',以便在定义时不会将$ mystr的内容作为命令执行。
这里是什么,我认为是来检查变量定义更清晰的方式:
var_defined() {
local var_name=$1
set | grep "^${var_name}=" 1>/dev/null
return $?
}
如下使用它:
if var_defined foo; then
echo "foo is defined"
else
echo "foo is not defined"
fi
另一种选择:the "list array indices" expansion:
$ unset foo
$ foo=
$ echo ${!foo[*]}
0
$ foo=bar
$ echo ${!foo[*]}
0
$ foo=(bar baz)
$ echo ${!foo[*]}
0 1
这个扩展到空字符串的唯一时间是当foo
未被设置,所以你可以与串条件检查:
$ unset foo
$ [[ ${!foo[*]} ]]; echo $?
1
$ foo=
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=bar
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=(bar baz)
$ [[ ${!foo[*]} ]]; echo $?
0
应任何的bash版本> = 3.0
的测试总结可用。
[ -n "$var" ] && echo "var is set and not empty"
[ -z "$var" ] && echo "var is unset or empty"
[ "${var+x}" = "x" ] && echo "var is set" # may or may not be empty
[ -n "${var+x}" ] && echo "var is set" # may or may not be empty
[ -z "${var+x}" ] && echo "var is unset"
[ -z "${var-x}" ] && echo "var is set and empty"
不进一步摆脱这种自行车,但想补充
shopt -s -o nounset
的东西,你可以添加到脚本的顶部,如果变量不是宣布任何地方,将错误在脚本中。您看到的消息是unbound variable
,但正如其他人提到它不会捕获空字符串或空值。为确保任何单个值不为空,我们可以测试一个变量,因为它的扩展名为${mystr:?}
,也称为美元符号扩展,这会与parameter null or not set
错误。
明确的方法检查确定将是一个变量被:
[ -v mystr ]
https://stackoverflow.com/a/9824943/14731包含一个更好的答案(一说是更具可读性和启用set -o nounset
作品)。它的工作方式大致如下:
if [ -n "${VAR-}" ]; then
echo "VAR is set and is not empty"
elif [ "${VAR+DEFINED_BUT_EMPTY}" = "DEFINED_BUT_EMPTY" ]; then
echo "VAR is set, but empty"
else
echo "VAR is not set"
fi
Bash Reference Manual是关于bash的权威信息来源。
下面是测试一个变量看,如果它存在的一个例子:
if [ -z "$PS1" ]; then
echo This shell is not interactive
else
echo This shell is interactive
fi
(从section 6.3.2。)
请注意,打开[
之后和]
之前的空格是而非可选。
提示的Vim用户
我有一个脚本,有几个声明如下:
export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"
但我希望他们推迟到任何现有值。所以我重新写了他们看起来像这样:
if [ -z "$VARIABLE_NAME" ]; then
export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"
fi
我能够在VIM使用快速正则表达式来自动完成:
s/\vexport ([A-Z_]+)\=("[^"]+")\n/if [ -z "$\1" ]; then\r export \1=\2\rfi\r/gc
这可以通过肉眼选择相关线路应用,然后打字:
。命令栏预填充:'<,'>
。粘贴上面的命令并回车。
测试这个版本的Vim:
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 22 2015 15:38:58)
Compiled by [email protected]
Windows用户可能需要不同的行尾。
- 1. 判断一个字符串是否是另一个子字符
- 2. 如何判断一个字符串是否是网址?
- 3. 如何判断某个字母是否在字符串中 - javascript
- 4. 在Perl中,如何判断字符串是否是数字?
- 5. 如何判断bash是否在Python脚本中特别逃避通配符
- 6. 是否有任何算法来判断一个字符串是否有意义
- 7. 如何判断一个字符串是否包含Guid作为子字符串?
- 8. 在bash中定义一个没有shell脚本的shell函数?
- 9. BASH:如何判断脚本是否使用退出?
- 10. 判断用户是否在shell脚本中有SUed?
- 11. 如何在bash shell脚本变量中查找子字符串
- 12. 如何判断字符串中是否有数字?
- 13. 如何判断一个字符串是否以hh:mm格式在python中?
- 14. Shell脚本:截断字符串
- 15. 如何判断某个方法是否在类中定义?
- 16. Bash shell脚本抓取一个子字符串?
- 17. 我如何判断一个字符串是否只包含字母和空格
- 18. shell脚本grep grep一个字符串
- 19. shell脚本与另一个字符串
- 20. 如何判断一个String是否真的是Java中的一个字符?
- 21. 如何判断const char *是否指向有效的字符串?
- 22. 比较在bash shell脚本,两个字符串变量
- 23. 如何在bash脚本中转义字符串
- 24. 使用bash shell脚本在2个字符串之间提取字符串
- 25. 如何判断字符串是URL还是本地路径?
- 26. 如何从shell脚本中判断调用它的shell是否是交互式shell?
- 27. 在shell脚本中检查字符串错误是否为空?
- 28. 如何判断字符串在元值中是空还是空?
- 29. 如何判断Request.Form中的值是否是一个数字? (C#)
- 30. 处理从一个字符串数组通配符扩展在bash shell脚本
请不要使用[-z“$ mystr”]而不是[-z $ mystr] – 2008-10-23 04:46:38
如何做相反的事情?我的意思是当字符串不为空 – flow 2011-06-17 15:46:39
@flow:怎么样`[-n“$ {VAR + x}”] && echo not null` – Lekensteyn 2011-08-16 17:49:31