为什么在 POSIX sh 中的 `test`/`[` 字符串比较中附加一个额外的字符?
Why append an extra character in `test`/`[` string comparison in POSIX sh?
在阅读了 Debian 的 /usr/bin/startx
之后,我发现了一些奇怪的东西:
mcookie=`/usr/bin/mcookie`
if test x"$mcookie" = x; then
echo "Couldn't create cookie"
exit 1
fi
我不明白为什么额外的 x
是必要的 - 不是等同于写以下内容吗?
mcookie=`/usr/bin/mcookie`
if test "$mcookie" = ""; then
echo "Couldn't create cookie"
exit 1
fi
我最初认为如果 mkcookie
变量碰巧未设置,sh
的早期版本可能会打印出一些错误(这不是唯一的例子;这些类型的比较是分散的在整个脚本中自由地)。但是经过进一步思考并没有多大意义,因为变量被引用并且 shell 会将其扩展为空字符串。
我仔细阅读了 Bash 手册页的 Dash,--posix
部分并检查了 POSIX 本身。它在 test: s1 = s2 True if the strings s1 and s2 are identical; otherwise, false
下什么也没说。我假设编写脚本的人知道他们在做什么 - 那么有人可以阐明这一点吗?
谢谢,
埃德温
以下是 Wooledge Bash Pitfall #4 的摘录:
You may have seen code like this:
[ x"$foo" = xbar ] # Ok, but usually unnecessary.
The x"$foo"
hack is required for code that must run on very ancient shells which lack [[
, and have a more primitive [
, which gets confused if $foo
begins with a -
. On said older systems, [
still doesn't care whether the token on the right hand side of the =
begins with a -
. It just uses it literally. It's just the left-hand side that needs extra caution.
Note that shells that require this workaround are not POSIX-conforming. Even the Heirloom Bourne shell doesn't require this (probably the non-POSIX Bourne shell clone that's still most widely in use as a system shell). Such extreme portability is rarely a requirement and makes your code less readable (and uglier).
如果您在本世纪的代码中发现它,那只是货物崇拜不断被不引用的人强化。
/usr/bin/startx
至少从 1993 年 2 月的 XFree86 2.1 开始就特别使用这个习惯用法,并且从那以后任何更新都可能只是匹配样式。
在阅读了 Debian 的 /usr/bin/startx
之后,我发现了一些奇怪的东西:
mcookie=`/usr/bin/mcookie`
if test x"$mcookie" = x; then
echo "Couldn't create cookie"
exit 1
fi
我不明白为什么额外的 x
是必要的 - 不是等同于写以下内容吗?
mcookie=`/usr/bin/mcookie`
if test "$mcookie" = ""; then
echo "Couldn't create cookie"
exit 1
fi
我最初认为如果 mkcookie
变量碰巧未设置,sh
的早期版本可能会打印出一些错误(这不是唯一的例子;这些类型的比较是分散的在整个脚本中自由地)。但是经过进一步思考并没有多大意义,因为变量被引用并且 shell 会将其扩展为空字符串。
我仔细阅读了 Bash 手册页的 Dash,--posix
部分并检查了 POSIX 本身。它在 test: s1 = s2 True if the strings s1 and s2 are identical; otherwise, false
下什么也没说。我假设编写脚本的人知道他们在做什么 - 那么有人可以阐明这一点吗?
谢谢, 埃德温
以下是 Wooledge Bash Pitfall #4 的摘录:
You may have seen code like this:
[ x"$foo" = xbar ] # Ok, but usually unnecessary.
The
x"$foo"
hack is required for code that must run on very ancient shells which lack[[
, and have a more primitive[
, which gets confused if$foo
begins with a-
. On said older systems,[
still doesn't care whether the token on the right hand side of the=
begins with a-
. It just uses it literally. It's just the left-hand side that needs extra caution.Note that shells that require this workaround are not POSIX-conforming. Even the Heirloom Bourne shell doesn't require this (probably the non-POSIX Bourne shell clone that's still most widely in use as a system shell). Such extreme portability is rarely a requirement and makes your code less readable (and uglier).
如果您在本世纪的代码中发现它,那只是货物崇拜不断被不引用的人强化。
/usr/bin/startx
至少从 1993 年 2 月的 XFree86 2.1 开始就特别使用这个习惯用法,并且从那以后任何更新都可能只是匹配样式。