在 Bash 中测试非零长度字符串:[ -n "$var" ] 或 [ "$var" ]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3869072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Test for non-zero length string in Bash: [ -n "$var" ] or [ "$var" ]
提问by AllenHalsey
I've seen Bash scripts test for a non-zero length string in two different ways. Most scripts use the -n
option:
我已经看到 Bash 脚本以两种不同的方式测试非零长度的字符串。大多数脚本使用该-n
选项:
#!/bin/bash
# With the -n option
if [ -n "$var" ]; then
# Do something when var is non-zero length
fi
But the -n option isn't really needed:
但实际上并不需要 -n 选项:
# Without the -n option
if [ "$var" ]; then
# Do something when var is non-zero length
fi
Which is the better way?
哪种方法更好?
Similarly, which is the better way for testing for zero-length:
同样,这是测试零长度的更好方法:
if [ -z "$var" ]; then
# Do something when var is zero-length
fi
or
或者
if [ ! "$var" ]; then
# Do something when var is zero-length
fi
回答by Paused until further notice.
Edit:This is a more complete version that shows more differences between [
(aka test
) and [[
.
编辑:这是一个更完整的版本,显示了[
(aka test
) 和[[
.
The following table shows that whether a variable is quoted or not, whether you use single or double brackets and whether the variable contains only a space are the things that affect whether using a test with or without -n/-z
is suitable for checking a variable.
下表显示了变量是否被引用,使用单括号还是双括号以及变量是否只包含空格是影响使用带或不带的测试-n/-z
是否适合检查变量的因素。
| 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b
| [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"
-----+------------------------------------+------------------------------------
unset| false false true false true true | false false false false true true
null | false false true false true true | false false false false true true
space| false true true true true false| true true true true false false
zero | true true true true false false| true true true true false false
digit| true true true true false false| true true true true false false
char | true true true true false false| true true true true false false
hyphn| true true true true false false| true true true true false false
two | -err- true -err- true -err- false| true true true true false false
part | -err- true -err- true -err- false| true true true true false false
Tstr | true true -err- true -err- false| true true true true false false
Fsym | false true -err- true -err- false| true true true true false false
T= | true true -err- true -err- false| true true true true false false
F= | false true -err- true -err- false| true true true true false false
T!= | true true -err- true -err- false| true true true true false false
F!= | false true -err- true -err- false| true true true true false false
Teq | true true -err- true -err- false| true true true true false false
Feq | false true -err- true -err- false| true true true true false false
Tne | true true -err- true -err- false| true true true true false false
Fne | false true -err- true -err- false| true true true true false false
If you want to know if a variable is non-zero length, do any of the following:
如果您想知道变量是否为非零长度,请执行以下任一操作:
- quote the variable in single brackets (column 2a)
- use
-n
and quote the variable in single brackets (column 4a) - use double brackets with or without quoting and with or without
-n
(columns 1b - 4b)
- 在单括号中引用变量(第 2a 列)
- 使用
-n
并引用单括号中的变量(第 4a 列) - 使用带或不带引号的双括号,带或不带
-n
(第 1b - 4b 列)
Notice in column 1a starting at the row labeled "two" that the result indicates that [
is evaluating the contentsof the variable as if they were part of the conditional expression (the result matches the assertion implied by the "T" or "F" in the description column). When [[
is used (column 1b), the variable content is seen as a string and not evaluated.
请注意,在第 1a 列中,从标记为“二”的行开始,结果表明[
正在评估变量的内容,就好像它们是条件表达式的一部分一样(结果与中的“T”或“F”隐含的断言匹配说明栏)。当[[
被使用(柱1b)中,可变内容被看作是一个字符串,不进行评价。
The errors in columns 3a and 5a are caused by the fact that the variable value includes a space and the variable is unquoted. Again, as shown in columns 3b and 5b, [[
evaluates the variable's contents as a string.
第 3a 和 5a 列中的错误是由变量值包含空格且变量未加引号引起的。同样,如第 3b 和 5b 列所示,[[
将变量的内容计算为字符串。
Correspondingly, for tests for zero-length strings, columns 6a, 5b and 6b show the correct ways to do that. Also note that any of these tests can be negated if negating shows a clearer intent than using the opposite operation. For example: if ! [[ -n $var ]]
.
相应地,对于零长度字符串的测试,第 6a、5b 和 6b 列显示了正确的方法。另请注意,如果否定比使用相反的操作显示出更清晰的意图,则可以否定这些测试中的任何一个。例如:if ! [[ -n $var ]]
。
If you're using [
, the key to making sure that you don't get unexpected results is quoting the variable. Using [[
, it doesn't matter.
如果您使用的是[
,确保不会得到意外结果的关键是引用变量。使用[[
,没关系。
The error messages, which are being suppressed, are "unary operator expected" or "binary operator expected".
被抑制的错误消息是“期望一元运算符”或“期望二元运算符”。
This is the script that produced the table above.
这是生成上表的脚本。
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }
o=/dev/null
echo ' | 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b'
echo ' | [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"'
echo '-----+------------------------------------+------------------------------------'
while read -r d t
do
printf '%-*s|' "$dw" "$d"
case $d in
unset) unset t ;;
space) t=' ' ;;
esac
[ $t ] 2>$o && t || f
[ "$t" ] && t || f
[ -n $t ] 2>$o && t || f
[ -n "$t" ] && t || f
[ -z $t ] 2>$o && t || f
[ -z "$t" ] && t || f
echo -n "|"
[[ $t ]] && t || f
[[ "$t" ]] && t || f
[[ -n $t ]] && t || f
[[ -n "$t" ]] && t || f
[[ -z $t ]] && t || f
[[ -z "$t" ]] && t || f
echo
done <<'EOF'
unset
null
space
zero 0
digit 1
char c
hyphn -z
two a b
part a -a
Tstr -n a
Fsym -h .
T= 1 = 1
F= 1 = 2
T!= 1 != 2
F!= 1 != 1
Teq 1 -eq 1
Feq 1 -eq 2
Tne 1 -ne 2
Fne 1 -ne 1
EOF
回答by codeforester
It is better to use the more powerful[[
as far as Bash is concerned.
就 Bash 而言,最好使用更强大的[[
。
Usual cases
常见情况
if [[ $var ]]; then # var is set and it is not empty
if [[ ! $var ]]; then # var is not set or it is set to an empty string
The above two constructs look clean and readable. They should suffice in most cases.
以上两个结构看起来干净且可读。在大多数情况下,它们应该足够了。
Note that we don't need to quote the variable expansions inside [[
as there is no danger of word splittingand globbing.
请注意,我们不需要引用内部的变量扩展,[[
因为没有分词和globbing 的危险。
To prevent shellcheck's soft complaints about [[ $var ]]
and [[ ! $var ]]
, we could use the -n
option.
为了防止shellcheck对[[ $var ]]
and的软抱怨[[ ! $var ]]
,我们可以使用该-n
选项。
Rare cases
罕见病例
In the rare case of us having to make a distinction between "being set to an empty string" vs "not being set at all", we could use these:
在我们必须区分“被设置为空字符串”与“根本没有被设置”之间的罕见情况下,我们可以使用这些:
if [[ ${var+x} ]]; then # var is set but it could be empty
if [[ ! ${var+x} ]]; then # var is not set
if [[ ${var+x} && ! $var ]]; then # var is set and is empty
We can also use the -v
test:
我们也可以使用-v
测试:
if [[ -v var ]]; then # var is set but it could be empty
if [[ ! -v var ]]; then # var is not set
if [[ -v var && ! $var ]]; then # var is set and is empty
if [[ -v var && -z $var ]]; then # var is set and is empty
Related posts and documentation
相关帖子和文档
There are a plenty of posts related to this topic. Here are a few:
有很多与此主题相关的帖子。以下是一些:
- How to check if a variable is set in Bash?
- How to check if an environment variable exists and get its value?
- How to find whether or not a variable is empty in Bash
- What does “plus colon” (“+:”) mean in shell script expressions?
- Is double square brackets [[ ]] preferable over single square brackets [ ] in Bash?
- What is the difference between single and double square brackets in Bash?
- An excellent answerby mklement0where he talks about
[[
vs[
- Bash Hackers Wiki -
[
vs[[
回答by Steven Penny
Here are some more tests
这里还有一些测试
True if string is not empty:
如果字符串不为空,则为真:
[ -n "$var" ]
[[ -n $var ]]
test -n "$var"
[ "$var" ]
[[ $var ]]
(( ${#var} ))
let ${#var}
test "$var"
True if string is empty:
如果字符串为空则为真:
[ -z "$var" ]
[[ -z $var ]]
test -z "$var"
! [ "$var" ]
! [[ $var ]]
! (( ${#var} ))
! let ${#var}
! test "$var"
回答by user1310789
An alternative and perhaps more transparent way of evaluating an empty environment variable is to use...
评估空环境变量的另一种可能更透明的方法是使用...
if [ "x$ENV_VARIABLE" != "x" ] ; then
echo 'ENV_VARIABLE contains something'
fi
回答by user2592126
The correct answer is the following:
正确答案如下:
if [[ -n $var ]] ; then
blah
fi
Note the use of the [[...]]
, which correctly handles quoting the variables for you.
请注意 的使用[[...]]
,它可以正确地为您处理引用变量。
回答by ghostdog74
Use case/esac
to test:
使用case/esac
测试:
case "$var" in
"") echo "zero length";;
esac