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

Gor*_*don 5 bash

如果下面应该返回 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" ]
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 8

\n
[ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]\n
Run Code Online (Sandbox Code Playgroud)\n
\n

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

\n
    \n
  1. \xc2\xb9的输出pwd
  2. \n
  3. !=,
  4. \n
  5. 变量的内容PS_APP_HOME
  6. \n
  7. ],
  8. \n
  9. -o,
  10. \n
  11. [,
  12. \n
  13. 另一个调用的输出pwd
  14. \n
  15. !=,
  16. \n
  17. 变量的内容PS_CUST_HOME,以及
  18. \n
  19. ]
  20. \n
\n

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

\n

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

\n

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

\n
    \n
  • 使用标准语法:

    \n
    if [ "$PWD" != "$PS_APP_HOME" ] && [ "$PWD" != "$PS_CUST_HOME" ]; then\n  echo current directory is neither the APP nor CUST home\nfi\n
    Run Code Online (Sandbox Code Playgroud)\n

    [(如果第一个命令成功使用&& shell(非)运算符,我们将运行第二个命令[)。

    \n
  • \n
  • 类似 Korn 的语法:

    \n
    if [[ $PWD != "$PS_APP_HOME" && $PWD != "$PS_CUST_HOME" ]]; then\n  echo current directory is neither the APP nor CUST home\nfi\n
    Run Code Online (Sandbox Code Playgroud)\n

    或者

    \n
    if [[ ! ($PWD = "$PS_APP_HOME" || $PWD = "$PS_CUST_HOME") ]]; then\n  echo current directory is neither the APP nor CUST home\nfi\n
    Run Code Online (Sandbox Code Playgroud)\n

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

    \n
  • \n
\n

虽然你也可以使用case

\n
case $PWD in\n  ("$PS_APP_HOME" | "$PS_CUST_HOME") ;;\n  (*) echo current directory is neither the APP nor CUST home\nesac\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

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

\n
if [[ ! (. -ef $PS_APP_HOME || . -ef $PS_CUST_HOME) ]]; then\n  echo current directory is neither the APP nor CUST home\nfi\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
if [ ! . -ef "$PS_APP_HOME" ] && [ ! . -ef "$PS_CUST_HOME" ]; then\n  echo current directory is neither the APP nor CUST home\nfi\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n
\n

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

\n

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

\n