1

我在他们在 if 比较中使用的 shell 脚本中多次看到"_"如下所示:

if [ "_$str" = "_" ]; then ....; fi

上面的代码通过比较检查 str 变量是否为空if [ "_$str" = "_" ]

为什么不使用if [ "$str" = "" ]?为什么要同时添加"_"两个字符串?

4

3 回答 3

11

据我所知,这是出于历史原因。曾经有(并且可能在一些不为人知的系统上仍然存在)shell 在处理空字符串(并且可能以破折号开头的字符串)时遇到了问题。因此,通过添加前缀来完全防止空字符串(和类似选项的字符串)的简单想法。今天所有常见的shell都不再有这些问题了。

于 2013-09-17T13:10:46.943 回答
2

我只能猜测在学习如何正确使用引号之前,您所看到的脚本的作者遇到了类似的问题

if [[ $str = "" ]]; then ....

如果 $str 为空,这将失败,因为参数扩展为空。然而

if [[ _$str = _ ]]

会起作用,但它是一个kludge。

于 2013-09-17T13:11:23.880 回答
1

请记住,这[是 command 的别名test。问题是如果你的字符串以破折号开头会发生什么?

在使用标准 Bourne shell 的旧版本中test,您会收到一个错误:

$ 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.

这不再是一个问题。[和是 Kornshell 和 BASH的test内部命令,这些 shell 可以处理这个问题。即使是较新版本的 test 也不再抛出:

$ test -gt = "some_string"  # No error.
$ echo $?
1

但是,较旧的脚本,以及那些从较老的计时器那里学习的人,或者在使用 Xenix 的 16 Mhz 386 芯片上运行 32 Mb 内存的系统是最先进的系统时重新编写脚本的人已经养成了这种习惯。我曾经使用x

if [ x$var = x$foo ]
于 2013-09-17T14:24:33.797 回答