【问题标题】:Why 'x' used in [ x"$VAR" = x"VALUE" ]?为什么在 [ x"$VAR" = x"VALUE" ] 中使用 'x'?
【发布时间】:2011-03-06 19:51:55
【问题描述】:

我可以在 unix shell 脚本中看到使用了以下构造

[ x"$VAR" = x"VALUE" ] 

而不是

[ "$VAR" = "VALUE" ] 

为什么?

【问题讨论】:

  • 似乎大部分是stackoverflow.com/questions/174119/…的副本
  • 如果您使用的是现代 shell,引用就足够了。使用“x”是一种不再需要的古老技术。
  • ...对于“现代”的非常松散定义来说确实如此; x"$foo" 成语至少自 1991 年以来就没有用过,只要避免目前标记为过时的各种test 使用模式(请参阅pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html 中的OB 标记;这些模式确实已经过时了因为它们会导致歧义,导致数据可能与test本身的语法混淆)。

标签: shell unix


【解决方案1】:

当 $VAR 为空时,它会给出语法错误[ = "VALUE"],因此使用 x

【讨论】:

  • 是的。如果你有兴趣提前学习很多这样的小东西,而不是偶然发现它们,我个人推荐 O'Reilly 的书Classic Shell Scripting,参见oreilly.com/catalog/9780596005955 .阅读本文后,许多更晦涩的 shell 脚本变得更容易理解了。
  • OP 的代码在扩展名周围使用了引号,这使得这不真实。
  • @CharlesDuffy:这完全取决于使用哪个 shell。有关此问题的其他答案,请参见 cmets。
  • @knittl,POSIX sh 标准于 1991 年发布。每个 兼容的外壳都有相关的属性。 1970 年代存在引用没有影响的壳,这不仅在今天无关紧要——十年前和十年前都无关紧要。
  • @knittl, ...are 在 POSIX 规范中有一些未定义的情况,"x$foo" 有所不同,但 (1) 它们不涉及空字符串 (相反,它们涉及正在测试的值恰好是()-a-o)的情况,并且(2)它们只有在-a 或@ 时才会发生987654329@ 用于将多个操作组合成一个 test 调用(至少自 2008 年发布标准以来,该语法已被标记为过时)。
【解决方案2】:

因为如果其中一个变量为空,shell 并不总是表现良好。

考虑如果$VAR 为空/null 且$VALUE 为“foo”,您的两个构造扩展为:

[ x = xfoo ]

[ = foo ]

由于是非法构造,后者会在某些 shell 中导致错误,而前者在任何情况下都是有效的。这在最新版本的 bash(甚至可能是旧版本的 bash)中不是问题,但从历史上看,这就是它的来源 - 除了偶尔遇到您所处情况的人感到困惑之外,几乎没有理由 这样做是为了与更广泛的 shell 兼容。

【讨论】:

  • 我的例子中有引号。我说的是 [ "x" = x"foo" ] 不是 [ x = xfoo ]
  • 使用引号(和现代 shell),您不需要 'x' -- [ "$var" = "val" ] 变为,当 var 为空时:[ "" = "val" ] 这完全是错误的,没有错误。跨度>
  • @AndrejDoyle,你能找出一个有这个错误的 shell 吗?甚至heirloom sh 也没有。 更容易识别的错误与空(但正确引用的)字符串无关,而是与仅包含 !-a-o( 或 @ 的字符串有关987654333@ 被误认为是test 语法。
【解决方案3】:

这是一种防止比较两边为空的古老技术。有些 shell 不能正确处理空字符串。

【讨论】:

【解决方案4】:

你有你的解释,但这是另一种方法,使用 case/esac 而不是 if/else

case "$VAR" in 
  "$VALUE" ) echo 'yes';;
  * ) echo 'no' ;;
esac

【讨论】:

    猜你喜欢
    • 2018-09-25
    • 2023-03-04
    • 1970-01-01
    • 2023-03-27
    • 2017-05-26
    • 2015-06-17
    • 2019-09-11
    • 2020-06-08
    • 1970-01-01
    相关资源
    最近更新 更多