Bashの条件が複数文の場合

Bashの条件が複数文の場合

次の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に到達します。

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

関数の末尾にUnexpected token "}"エラーが発生します(この行は関数の一部です)。

フォーマットされた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

しかし、最初に達成しようとしていたように、1行にネストされた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

&&使用する方法は||条件ではなくリストです。

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

関連情報