我在shell脚本中多次看到他们在if比较中使用"_"
,如下所示:
if [ "_$str" = "_" ]; then ....; fi
上面的代码检查str变量是否为空,并带有比较if [ "_$str" = "_" ]
。
为什么不使用if [ "$str" = "" ]
?为什么在两个字符串中添加"_"
?
答案 0 :(得分:11)
据我所知,这是出于历史原因。曾经有(并且可能在一些模糊的系统上)炮弹处理空字符串(也许是以破折号开头的字符串)。因此,通过添加前缀来完全防止空字符串(以及类似选项的外观)的简单想法。今天所有常见的炮弹都不再存在这些问题了。
答案 1 :(得分:2)
我只能在学习如何正确使用引号之前猜测,你看过的脚本的编写者遇到了像
这样的问题if [[ $str = "" ]]; then ....
如果$ str为空将失败,因为参数扩展为空。而
if [[ _$str = _ ]]
会起作用,但它是一种kludge。
答案 2 :(得分:1)
请记住,[
是命令test
的别名。问题是如果你的字符串以破折号开头会发生什么?
在旧版本的test
中使用标准Bourne shell时,会出现错误:
$ test -gt = "some_string"
invalid argument
if
$ string="-gt"
$ if [ "$string" = "some_other_string" ]
> then
> echo "Match"
> else
> echo "No Match"
> fi
if: invalid argument
那是因为test
命令会看到带有破折号的参数并假设它是一个命令参数,然后它是一个无效的命令参数,或者命令的格式不正确。如果您使用[[
代替[
,则根本不是问题,因为[[
是if
的内置测试。
这不再是问题。 [
和test
是Kornshell和BASH的内部命令,这些shell可以处理此问题。即使是较新版本的测试也不再被抛出:
$ test -gt = "some_string" # No error.
$ echo $?
1
然而,较老的脚本,以及那些从较旧的计时器中学习或者在使用Xenix的16 Mhz 386芯片上运行32 Mb内存的系统回来编写脚本的人是最先进的系统已经进入习惯。我用x
:
if [ x$var = x$foo ]