Bash:安全删除括号内所有出现的-n? [重复]

问题描述 投票:0回答:2

这个问题在这里已有答案:

我最近在我的bash脚本中发现了这个“bug”;

if [ "$var" ]; then
    echo "Condition is true"
fi

我的意思是检查$var是否非空,即[ -n "$var" ]。碰巧的是,如果没有-n,代码似乎完全正常。同样,我发现我可以用[ -z "$var" ]替换[ ! "$var" ]

我倾向于喜欢基于其他语言中变量的(非)空虚的隐含的错误(真实性),因此我也可以在bash中采用这种模式。这样做是否有任何危险,即两组语法不相等的边缘情况?

bash shell boolean is-empty truthiness
2个回答
1
投票

所以我们替换:

-n "$var"   ->    "$var" 
-z "$var"   ->    ! "$var"

这看起来不错,有些人这样做。有些情况下删除会有害并导致语法错误。这些角落案例特别包括时间,其中var等于有效的test参数。防爆。 var=-nvar="!"

例如:

$ 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,我们可以找到以下应用说明:

这两个命令:

测试“$ 1” 测试! “$ 1”

在一些历史系统上无法可靠地使用。如果使用这样的字符串表达式并且$ 1扩展为'!','('或已知的一元主要,则会出现意外的结果。更好的结构是:

测试-n“$ 1” 测试-z“$ 1”

所以我认为只要你不使用“某些历史系统”,你就是安全的。但值得冒风险吗?你必须自己回答。

也就是说,主观:我更重视可维护性和可读性,然后保存到类型3字符并找到-n-z更具可读性。 -n的意图很明确 - 测试字符串是否具有-nonzero长度。 -z的意图也很明确 - 测试字符串是否有-zero长度。我发现编写[ "$var" ][ ! "$var" ]让其他人感到困惑。起初它看起来像$var[ ]中有一些特殊含义。

我最近在我的bash脚本中发现了这个“bug”

这不是一个错误,这是一个功能!


0
投票

首先,您使用单个括号。这意味着您使用的是test命令而不是Bash-builtin函数。从手册:

test EXPRESSION[ EXPRESSION ]:退出EXPRESSION返回的状态

-n STRINGSTRING的长度非零。

STRING:相当于-n STRING

来源:man test

这应该回答你的问题。

此外:

! EXPRESSIONtest返回EXPRESSION的真假是假的

-z STRING:如果test的长度为零,则STRING返回true。

这意味着[ ! STRING ]相当于[ -z STRING ]

© www.soinside.com 2019 - 2024. All rights reserved.