Bash:删除括号内所有出现的 -n 是否安全?
Bash: Safe to remove all occurrences of -n inside brackets?
我最近在我的 bash 脚本中发现了这个 "bug";
if [ "$var" ]; then
echo "Condition is true"
fi
我的意思是检查 $var
是否非空,即 [ -n "$var" ]
。碰巧的是,没有 -n
,代码似乎工作得很好。同样,我发现我可以用 [ ! "$var" ]
.
替换 [ -z "$var" ]
我倾向于喜欢这种基于其他语言中变量的(非)空性的隐式虚假性(真实性),因此我可能也会在 bash 中采用这种模式。这样做有什么危险吗,即两组语法不等价的边缘情况?
所以我们代入:
-n "$var" -> "$var"
-z "$var" -> ! "$var"
这看起来不错,有些人也这样做了。在极端情况下,删除会有害并导致语法错误。这些极端情况特别包括时间,其中 var
等于有效的 test
参数。前任。 var=-n
或 var="!"
等
例如:
$ v1="-n" v2=""; [ -n "$v1" -o -z "$v2" ]; echo $?
0
但是
$ v1="-n" v2=""; [ "$v1" -o ! "$v2" ]; echo $?
bash: [: too many arguments
2
也就是说,我无法在我的系统 (bash 5.0.0) 上找到不使用 -o
和 -a
来破解它的方法。无论如何,测试手册页建议使用 &&
和 ||
而不是 -a
和 -o
.
但是在POSIX specification test中我们可以找到如下应用笔记:
The two commands:
test ""
test ! ""
could not be used reliably on some historical systems. Unexpected
results would occur if such a string expression were used and
expanded to '!', '(', or a known unary primary. Better constructs are:
test -n ""
test -z ""
所以我认为只要你不使用"some historical systems",你就是安全的。但值得冒险吗?你必须自己回答。
也就是说,主观的:我更看重可维护性和可读性,然后节省输入 3 个字符并发现 -n
和 -z
更具可读性。 -n
的意图很明确 - 测试字符串的长度是否为 -n
onzero。 -z
的意图也很明确 - 测试字符串是否具有 -z
ero 长度。我发现写 [ "$var" ]
和 [ ! "$var" ]
会让其他人感到困惑。起初看起来 $var
在 [
]
.
中有一些特殊的含义
I recently found this "bug" in my bash script
这不是错误,这是一个功能!
首先,你使用单括号。这意味着您正在使用 test
命令而不是 Bash-内置函数。来自手册:
test EXPRESSION
or [ EXPRESSION ]
: this exits with the status returned by EXPRESSION
-n STRING
: the length of STRING
is nonzero.
STRING
: equivalent to -n STRING
source: man test
这应该可以回答您的问题。
此外:
! EXPRESSION
: test
returns true of EXPRESSION
is false
-z STRING
: test
returns true if the length of STRING
is zero.
这意味着 [ ! STRING ]
等同于 [ -z STRING ]
。
我最近在我的 bash 脚本中发现了这个 "bug";
if [ "$var" ]; then
echo "Condition is true"
fi
我的意思是检查 $var
是否非空,即 [ -n "$var" ]
。碰巧的是,没有 -n
,代码似乎工作得很好。同样,我发现我可以用 [ ! "$var" ]
.
[ -z "$var" ]
我倾向于喜欢这种基于其他语言中变量的(非)空性的隐式虚假性(真实性),因此我可能也会在 bash 中采用这种模式。这样做有什么危险吗,即两组语法不等价的边缘情况?
所以我们代入:
-n "$var" -> "$var"
-z "$var" -> ! "$var"
这看起来不错,有些人也这样做了。在极端情况下,删除会有害并导致语法错误。这些极端情况特别包括时间,其中 var
等于有效的 test
参数。前任。 var=-n
或 var="!"
等
例如:
$ v1="-n" v2=""; [ -n "$v1" -o -z "$v2" ]; echo $?
0
但是
$ v1="-n" v2=""; [ "$v1" -o ! "$v2" ]; echo $?
bash: [: too many arguments
2
也就是说,我无法在我的系统 (bash 5.0.0) 上找到不使用 -o
和 -a
来破解它的方法。无论如何,测试手册页建议使用 &&
和 ||
而不是 -a
和 -o
.
但是在POSIX specification test中我们可以找到如下应用笔记:
The two commands:
test ""
test ! ""could not be used reliably on some historical systems. Unexpected results would occur if such a string expression were used and expanded to '!', '(', or a known unary primary. Better constructs are:
test -n ""
test -z ""
所以我认为只要你不使用"some historical systems",你就是安全的。但值得冒险吗?你必须自己回答。
也就是说,主观的:我更看重可维护性和可读性,然后节省输入 3 个字符并发现 -n
和 -z
更具可读性。 -n
的意图很明确 - 测试字符串的长度是否为 -n
onzero。 -z
的意图也很明确 - 测试字符串是否具有 -z
ero 长度。我发现写 [ "$var" ]
和 [ ! "$var" ]
会让其他人感到困惑。起初看起来 $var
在 [
]
.
I recently found this "bug" in my bash script
这不是错误,这是一个功能!
首先,你使用单括号。这意味着您正在使用 test
命令而不是 Bash-内置函数。来自手册:
test EXPRESSION
or[ EXPRESSION ]
: this exits with the status returned byEXPRESSION
-n STRING
: the length ofSTRING
is nonzero.
STRING
: equivalent to-n STRING
source:
man test
这应该可以回答您的问题。
此外:
! EXPRESSION
:test
returns true ofEXPRESSION
is false
-z STRING
:test
returns true if the length ofSTRING
is zero.
这意味着 [ ! STRING ]
等同于 [ -z STRING ]
。