bash 中的多语句 if 条件

bash 中的多语句 if 条件

我想在 if 条件下执行几个语句,如下所示:

[[ -e cli.tar.gz ]] && `tar -xvf cli.tar.gz -C ~/` || 
        echo "cli.tar.gz can not be found. Exiting" >&2 && exit 1

发生的情况是,当找到 cli.tar.gz 并对其进行焦油处理时,就到达了出口 1,即与我想要实现的目标完全相反,因此我在 OR 之后的部分周围添加了括号,如下所示

[[ -e cli.tar.gz ]] && tar -xvf cli.tar.gz -C ~/ || 
   { echo "cli.tar.gz can not be found. Exiting" >&2; exit 1; }

我在函数末尾收到错误意外标记“}”(此行是函数的一部分)

我通过编写一个良好格式的 if 条件解决了我的问题

if [[ -e cli.tar.gz ]]
then
    if [[ ! `tar -xvf cli.tar.gz -C ${UDM_REMOTE}` ]]
    then
        echo "cli.tar.gz can not be found. Exiting" >&2; exit 1;
    fi
fi

但是,像我最初尝试实现的那样,在一行中执行嵌套 if 条件的解决方案是什么?

更新1 感谢 @uwe 和 @goldilocks 的回答,我更新了声明如下,现在可以使用了

[[ ! -e cli.tar.gz ]] && ! `tar -xvf cli.tar.gz -C ~/` && \ 
  echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 && exit 1

答案1

if [[ ! -e cli.tar.gz ]] || ! tar -xvf cli.tar.gz -C ~/ ; then 
    echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 && exit 1
fi

或者,如果您想完全避免if

( [[ ! -e cli.tar.gz ]] || ! tar -xvf cli.tar.gz -C ~/ ) && { echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 ; exit 1 ; }

答案2

if [[ -e cli.tar.gz && ( $(tar -xvf cli.tar.gz -C ~/) && $? != 0 ) ]]; then 
    echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 && exit 1
fi

答案3

&&您使用and的方式||是作为列表,而不是条件。

Lists
   A list is a sequence of one or more pipelines separated by one of the 
   operators ;, &, &&, or ⎪⎪, and optionally terminated by one of ;, &, or 
   <newline>.

   Of these list operators, && and ⎪⎪ have equal precedence, followed by ; 
   and &, which have equal precedence.

   A sequence of one or more newlines may appear in a list instead of a 
   semicolon to delimit commands.

   If a command is terminated by the control operator &, the shell executes 
   the command in the background in a subshell.  The shell does not wait for 
   the command  to  finish,  and the  return  status  is 0.  Commands 
   separated by a ; are executed sequentially; the shell waits for each 
   command to terminate in turn.  The return status is the exit status of
   the last command executed.

   AND and OR lists are sequences of one of more pipelines separated by the 
   && and ⎪⎪ control operators, respectively.  AND and OR lists are executed 
   with left associativity.   An AND list has the form

          command1 && command2

   command2 is executed if, and only if, command1 returns an exit status of 
   zero.

   An OR list has the form

          command1 ⎪⎪ command2

   command2 is executed if and only if command1 returns a non-zero exit 
   status.  The return status of AND and OR lists is the exit status of the 
   last command executed in the list.

如果你看一下这个标题为“SO Q&A”的问题:BASH 中的简单逻辑运算符,@Gilles 的答案在解释如何应对 Bash 中的 if/then 块方面尽可能简洁。

重构运行#1

所以你的陈述的重构版本if/then

[[ -e cli.tar.gz && `tar -xvf cli.tar.gz -C ~/` || 
        echo "cli.tar.gz can not be found. Exiting" >&2 && exit 1

看起来像这样:

if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1; fi

或者为了可读性而扩展:

if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then 
  echo "cli.tar.gz can not be found. Exiting" >&2
  exit 1
fi

示例运行

样本数据。压缩包的内容:

$ tar ztvf cli.tar.gz 
drwxrwxr-x saml/saml         0 2013-11-13 08:26 1/
drwxrwxr-x saml/saml         0 2013-11-13 08:26 1/2/
drwxrwxr-x saml/saml         0 2013-11-13 08:26 1/2/3/
drwxrwxr-x saml/saml         0 2013-11-13 08:26 1/2/3/4/

文件信息:

$ ls -l cli.tar.gz 
-rw-rw-r-- 1 saml saml 146 Nov 13 08:27 cli.tar.gz

$ ls out/
1

运行我们的命令:

$ if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1; fi

什么都没发生。如果我们删除输出目录。out:

$ mv out out_ORIG

并重新运行:

$ if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; fi
tar: out: Cannot chdir: No such file or directory
tar: Error is not recoverable: exiting now
cli.tar.gz can not be found. Exiting

发生了什么?对于一个人来说,您通常不想像您尝试那样在 if/then 中混合运行命令。有太多的问题可能会出错。

重构运行 #2

相反,我会像这样构建我的代码,因为它为我们提供了处理突然出现的问题的最简单路径,而不是尝试构建一些荒谬的代码,即使你(作者)也会在 6 个月内努力理解你在做什么!

if [[ -e cli.tar.gz ]]; then 
  cmdOutput=$(tar xvf cli.tar.gz -C out 2>&1); 
  if [[ $? != 0 ]]; then 
    echo "cli.tar.gz can not be found. Exiting" >&2
    exit 1
  fi
fi

例子

$ ls -l |grep -E "cli|out"
-rw-rw-r-- 1 saml saml  146 Nov 13 08:27 cli.tar.gz
drwxrwxr-x 3 saml saml 4096 Nov 13 09:28 out

现在运行我们的命令(什么也没有发生):

$ if [[ -e cli.tar.gz ]]; then cmdOutput=$(tar xvf cli.tar.gz -C out 2>&1); if [[ $? != 0 ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1;fi;fi
$ 

现在运行我们的命令(不存在 dir.out):

$ rm -fr out
$ ls -l |grep -E "cli|out"
-rw-rw-r-- 1 saml saml  146 Nov 13 08:27 cli.tar.gz

$ if [[ -e cli.tar.gz ]]; then cmdOutput=$(tar xvf cli.tar.gz -C out 2>&1); if [[ $? != 0 ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1;fi;fi
cli.tar.gz can not be found. Exiting

相关内容