サブシェルなしで複数の条件がある場合はバッシングしませんか?

サブシェルなしで複数の条件がある場合はバッシングしませんか?

シェルifステートメントで複数の条件を組み合わせて組み合わせを無効にしたいと思います。単純な条件の組み合わせについては、次の作業コードがあります。

if [ -f file1 ] && [ -f file2 ] && [ -f file3 ] ; then
  # do stuff with the files
fi

これは素晴らしい作品です。これを否定するには、次の作業コードを使用できます。

if ! ( [ -f file1 ] && [ -f file2 ] && [ -f file3 ] ) ; then
  echo "Error: You done goofed."
  exit 1
fi
# do stuff with the files

これは期待どおりに機能します。しかし、私はかっこが実際に何をしているのか分からないことを発見しました。私考えるグループ化にのみ使用しますが、実際にサブシェルは作成されますか? (どうすればわかりますか?)では、サブシェルを作成せずに条件をグループ化する方法はありますか?

答え1

{ list;}代わりに、以下を使用する必要があります(list)

if ! { [ -f file1 ] && [ -f file2 ] && [ -f file3 ]; }; then
  : do something
fi

両方グループ化コマンドしかし、{ list;}現在のシェル環境でコマンドを実行します。

リストと逆方向の単語を区別するには;inが必要です。他の区切り文字も使用できます。次のスペース(またはその他の区切り文字)も必要です。{ list;}}{

答え2

到着持ち運べるシェルで複雑な条件を無効にするには、以下を適用する必要があります。ドモーガンの法則[否定を呼び出しに最後まで押し込みます...

if [ ! -f file1 ] || [ ! -f file2 ] || [ ! -f file3 ]
then
    # do stuff
fi

then :; else...または...を使用する必要があります。

if [ -f file1 ] && [ -f file2 ] && [ -f file3 ]
then :
else
  # do stuff
fi

if ! commandポータブルではありません[[

完全な移植性が不要な場合、シェルスクリプトを書かない。あなたは実際にもっと/usr/bin/perlランダムに選択されたUnixでは、あなたよりも多くの人を見つける可能性がありますbash

答え3

このtest機能を使用すると、必要なものを正確に取得できます。マニュアルページからtest

 ! expression  True if expression is false.
 expression1 -a expression2
               True if both expression1 and expression2 are true.
 expression1 -o expression2
               True if either expression1 or expression2 are true.
 (expression)  True if expression is true.

したがって、状況は次のようになります。

if [ -f file1 -a -f file2 -a -f file3 ] ; then
    # do stuff with the files
fi

否定するには、エスケープされた角かっこを使用してください。

if [ ! \( -f file1 -a -f file2 -a -f file3 \) ] ; then
    echo "Error: You done goofed."
    exit 1
fi
# do stuff with the files

答え4

これはあなたの主な質問に対する完全な答えではありませんが、あなたのコメントであなたが複合テスト(読めるファイル)に言及したことがわかりました。

if [ -f file1 ] && [ -r file1 ] && [ -f file2 ] && [ -r file2 ] && [ -f file3 ] && [ -r file3 ]

たとえば、シェル関数を定義してこれをもう少し強化できます。

readable_file()
{
    [ -f "$1" ]  &&  [ -r "$1" ]
}

[ $# = 1 ]好みに合わせて(例:)にエラー処理を追加します。上記の最初のステートメントは、if次のようにまとめることができます。

if readable_file file1  &&  readable_file file2  &&  readable_file file3

関数名を短くすることで、さらに短くすることができます。同様に、関数に否定を定義not_readable_file()(または省略)して含めることができます。nrf

関連情報