IF 测试返回太多路径比较参数

IF 测试返回太多路径比较参数

如果下面应该返回 true,但它实际上失败,并在 bash shell 中执行时报告参数过多的错误。我想我遵循了所有带双引号的准则,但无法弄清楚为什么它在我的生活中失败了......有什么想法吗?

#!/usr/bin/bash
# These are the values in the environment
#echo ">"$PS_APP_HOME"<"  => >/app/psoft/app_85909<
#echo ">"PS_CUST_HOME"<"  => >/app/psoft/cust_85909<
#echo ">"$(pwd)"<"        => >/app/psoft/app_85909<

if [ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

答案1

[ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

[使用以下参数调用命令:

  1. 输出pwd1,
  2. !=,
  3. 变量的内容PS_APP_HOME
  4. ],
  5. -o,
  6. [,
  7. 另一个调用的输出pwd
  8. !=,
  9. 变量的内容PS_CUST_HOME,以及
  10. ]

本来]是最后一个参数,所以当[看到-o第一个参数之后],它会感到困惑。

[有一个已弃用的-o运算符或者,但这意味着用作[ some-condition -o some-other-condition ].然而,不应使用它,因为它会导致不可靠的测试表达式。

在这里,使用或者也没有道理。当前工作目录不能同时是某项 ( $PS_APP_HOME) 和其他项 ( ),因此或$PS_CUSTOM_HOME至少其中之一为真。想必你的意思是"$(pwd)" != "$PS_APP_HOME""$(pwd)" != "$PS_CUST_HOME"代替或者。所以:

  • 使用标准语法:

    if [ "$PWD" != "$PS_APP_HOME" ] && [ "$PWD" != "$PS_CUST_HOME" ]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    [(如果第一个命令成功,我们将运行第二个命令&& (不是[) 运算符)。

  • 类似 Korn 的语法:

    if [[ $PWD != "$PS_APP_HOME" && $PWD != "$PS_CUST_HOME" ]]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    或者

    if [[ ! ($PWD = "$PS_APP_HOME" || $PWD = "$PS_CUST_HOME") ]]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    其中[[...]]是一个有自己的特殊构造条件表达式微语言代码里面也有一些&&(与)/ ||(或),!(非)布尔运算符。

虽然你也可以使用case

case $PWD in
  ("$PS_APP_HOME" | "$PS_CUST_HOME") ;;
  (*) echo current directory is neither the APP nor CUST home
esac

$PWD类似$(pwd),只是它更高效,因为它不需要分叉另一个进程并通过管道获取其输出,并且意味着如果当前工作目录的路径以换行符结尾,它仍然可以工作。²

请注意,上面的双引号很重要,我只将它们放在绝对必要的位置(以防止在构造的/运算符的参数中出现 split+glob[并防止变量值被视为参数中的模式或),虽然有!==[[...]]case全部引用的扩展不会造成损害。

除了进行词法比较之外,还要注意 ksh/bash/zsh[[....]]和大多数[实现(包括[内置的bash支持运算符)来-ef检查两个文件是否相同(在符号链接解析之后),因此您可以使用它而不是=

if [[ ! (. -ef $PS_APP_HOME || . -ef $PS_CUST_HOME) ]]; then
  echo current directory is neither the APP nor CUST home
fi

或者对于sh(大多数sh):

if [ ! . -ef "$PS_APP_HOME" ] && [ ! . -ef "$PS_CUST_HOME" ]; then
  echo current directory is neither the APP nor CUST home
fi

这里也使用.它不同于$PWD$(pwd)保证引用当前工作目录。

这样,如果$PWD/opt/app/some/link/to/app并且$PS_APP_HOME/opt/./app/opt/foo/../app/opt//app例如,那仍然有效。


¹ 删除所有尾随换行符,因此可能不是当前工作目录。

² 在某些 shell 中,$PWD如果当前工作目录已在您脚下重命名,则可能会给您提供过时的信息。但话又说回来,在某些 shell 中也是如此,它们只输出/ /pwd的值$PWD并且仅更新它。cdpushdpopd

答案2

if [ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

这在语法上是不正确的,这就是您收到报告的错误的原因。

如果您想将其作为一项测试来执行,则应该是:

if [ "$(pwd)" != "$PS_APP_HOME" -o "$(pwd)" != "$PS_CUST_HOME" ]

或者,如果您想让表达式完全分开并bash为您处理逻辑“或”:

if [ "$(pwd)" != "$PS_APP_HOME" ] || [ "$(pwd)" != "$PS_CUST_HOME" ]

相关内容