1. 概要

コマンドラインで作業する場合、条件が満たされた場合にのみ実行するためにいくつかのプロシージャが必要になる場合があります。 例を想像してみましょう。ファイルの特性に応じてコマンドのリストを実行します。たとえば、ファイルが存在する場合は、サイズ、名前、タイプなどです。

GNU / Linuxは、それを実現するのに役立つ非常に強力なツールのセットを提供してくれます。

このチュートリアルでは、条件式について説明し、これらの式の使用法を明確にするためにいくつかの例を作成します。

2. &&と||を使用した条件式

シェル内のすべてのコマンドは条件式であることに注意してください。各コマンドが終了ステータスとして整数を返すため、成功–0または失敗–1を示します。

シェルを使用している場合、通常、「 ; 「、 &&、 または||。

The && および|| トークンを使用すると、コマンドを終了ステータスを使用して接続できます。

The && トークンは、左側の命令の終了ステータスがゼロの場合にのみ、右側にあるものを実行するコマンドをチェーンします。

そして|| トークン、左側の命令の終了ステータスがゼロとは異なる場合にのみ、右側にあるものを実行するコマンドをチェーンします。

明確にするための簡単な例を作成しましょう。

$ (exit 0) && echo True
True
$ (exit 1) || echo False
False

これらのトークンについて理解したので、それをどのように使用できるかを見てみましょう。

まず、some_fileという名前のファイルを次の内容で作成しましょう。

$ cat << __end > some_file
foo
this string exists
bar
__end

ここで、 grepコマンドを使用して、ファイルに文字列が存在する場合にテキストを表示する方法を見てみましょう。

$ grep -q "this string exists" some_file && { echo "Everything"; echo "is all right"; }

最初の命令のステータスは0であるため、このコマンドラインの出力は次のようになります。

Everything
is all right

それでは、次のことを試してみましょう。

$ grep -q "this string doesn't exist" some_file || { echo "Not"; echo "today"; }

This time, the string we searched for doesn’t exist in the file, so the first instruction returns with a 1 – failure exit status. これは、このコマンドラインの出力が次のようになることを意味します。

Not
today

このことを念頭に置いて、これらのトークンでコマンドをチェーンすることでコマンドを作成できると考えさせられます。

同じファイルと同じコマンドを使用してみましょう。

$ grep -q "this string doesn't exist" some_file \
&& { echo "Everything"; echo "is all right"; } \
|| { echo "Not"; echo "today"; }

式を詳しく見てみましょう。

ここでは、 -qパラメーターを使用して、stdout の通常の出力ではなく、終了ステータスを取得します。

その終了ステータスの場合:

  • 0の場合(文字列がファイル内にある場合)、コマンドのリストは && トークンが実行されます
  • 終了ステータスが0でない場合(文字列がファイルにない場合)、トークンの右側にあるもの && 実行されません。 代わりに、トークンの右側の指示|| 実行されます

したがって、このコマンドの結果は次のようになります。

Not
today

これらのトークンを使用してコマンドを連鎖させる別の例を見てみましょう。

$ ( echo "Here 1"; exit 1 ) \
    && ( echo "Here 2" ) \
    && ( echo "Here 3" ) \
    || ( echo "Here 4"; exit 4 ) \
    && ( echo "Here 5"; exit 5 ) \
    || ( echo "Here 6"; exit 6 ) \
    || ( echo "Here 7"; exit 0 ) \
    && ( echo "Here 8" )

そして、出力は次のようになります。

Here 1
Here 4
Here 6
Here 7
Here 8

要約すると、私たちはそれを言うことができます &&と|| トークンは、ANDおよびOR論理演算と同等です 、これにより、命令フローのコースを制御できます。 ただし、 if-else 構文として(非常に注意深く)使用することもできます。

3. ifを使用してより複雑な式を作成する

前の例では、コマンドが条件式であるという事実のおかげで、コマンドのリストを明確に表現できることを確認しました。 ただし、この構文は、より複雑なコマンドでは扱いにくい場合があります。

物事をより明確に保ち、命令の流れを明確にする新しい方法を作成するために、シェルにはキーワードがあります:if、then、elif、else、fi。

したがって、たとえば、 if then else 、およびfiキーワードを使用してみましょう。

$ if
    ( echo "Here 1" )
    ( echo "Here 2" )
    ( echo "Here 3" )
then
echo Inside the \"then\" sentence
else
echo Inside the \"else\" sentence
fi

そして、出力は次のようになります。

Here 1
Here 2
Here 3
Inside the "then" sentence

それでは、次のことを試してみましょう。

$ if
    ( echo "Here 1" )
    ( echo "Here 2"; exit 2 )
    ( echo "Here 3"; exit 3 )
then
    echo Inside the \"then\" sentence
else
    echo Inside the \"else\" sentence
fi

そして、出力は次のようになります。

Here 1
Here 2
Here 3
Inside the "else" sentence

これは、この構文が最後に実行されたコマンドのステータスに焦点を合わせているためです。 これが、ステータスがゼロ以外のコマンドの後に「Here 3」を出力する理由であり、シェルがelseブロックに入った理由でもあります。

4. [、 テスト、 [[、および((、トークン

シェルには通常、条件式を使用するトークン [ test 、および[[が組み込まれています。

これらのトークンはそれぞれ異なりますが、後でその違いについて説明します。 ここで、 [テスト、および[[の共通点に焦点を当てましょう。

最初の例では、標準の/ homeディレクトリを使用して、ファイルがディレクトリであるかどうかを確認する方法を見てみましょう。

$ [ -d /home ] && echo "It's a directory"
It's a directory

ここでは、ファイルが存在し、ディレクトリであるかどうかをチェックする -d オプションを使用し、式を[および]トークンで囲みました。

次に、が2つの文字列が等しいかどうかをチェックする別の例を見てみましょう:

$ [ "this string" = "THIS STRING" ] \
    && echo They are equals \
    || echo They are different

そして、出力は次のようになります。

They are different

もちろん、「-eq」、「-ne」、「-lt」、「-le」、「-gt」、「-ge」のいずれかのオプションを使用して、整数を比較する非常によく似た例を作成できます。 」。

この式を[]トークンで囲み、 -ltオプションを使用して、一方の整数がもう一方の整数よりも小さいかどうかを比較してみましょう

$ [ 3 -lt 6 ] && echo "It's less than"
It's less than

ここにリストしたの例は、[、[[、またはテストコマンドのいずれかを使用して作成できることに注意してください。

それでは、各トークンとコマンドの機能と、それらのいくつかの違いについて少し掘り下げてみましょう。

4.1. [およびテストビルトイン

[およびtestは、前のセクションでリストした操作を実行するのに役立つ組み込みです。

[が組み込まれているため、条件式を囲むことができます。 これは、組み込みのtestと同じ有効性を持ちます。

言い換えると:

$ [ "string1" = "string2" ]

それはほとんど同じです:

$ test "string1" = "string2"

4.2. [[キーワード

以前のトークンと比較すると、 [[はキーワードであり、組み込みとは異なります。

ビルトインは、外部の実行可能ファイルではなく、シェルで実行されるコマンドまたは関数です。

キーワードは、シェルが特別であると見なす単語です。 したがって、シェルがキーワード[[を見つけた場合、シェルは終了を探します]]。 compgen-k。と入力してリストできます。

また、 [[キーワードは、Bashなどの一部のシェルの拡張です。

4.3. ((トークン

((は、式を算術式として評価できるようにするいくつかのシェルの拡張です。

これを使用する例を見てみましょう:

(( var < 10 ))
(( var++ ))
(( var=1; var<=10; var++ ))

式の値がゼロ以外の場合、この演算子の終了ステータスは0になります。 それ以外の場合、戻りステータスは1です。

4.4. [[、[の違い

[[[。の主な違いのいくつかを見てみましょう

まず、4.1と4.2のセクションで見たように、 [[はシェルのキーワードですが、[とtestはシェルビルトインです

もう1つの重要な違いは、 [はPOSIXですが、[[はそうではありません。

使用する場合 < また >> 演算子、内部で使用する場合はエスケープする必要があります [

$ [ "a" \< "b" ]

キーワード[[内でそれらを使用したい場合はそうではありません。

もう1つの注目すべき違いは、 [[キーワードは現在のロケールを使用して辞書式順序でソートするのに対し、[はASCII順序を使用することです。

次に、 && および|| 演算子は、トークンの各ペア内で異なります。

これは機能しますが:

$ [[ 1 = 1 && 2 = 2 ]] # returns True

この場合は次のことはしません。

$ [ 1 = 1 && 2 = 2 ] # returns a Bash error

ただし、次のようにすることで同じように操作できます。

$ [ 1 = 1 ] && [ 2 = 2 ]

これは、2.1のセクションで見たように、シェル内のすべてのコマンドが条件式であるためです。

言い換えると: [1 = 1] 戻り値真実そして、トークンの助けを借りて && 、 それから [2 = 2] 実行され、また返されます真実 。 次に、結合された文はtrueを返します。

トークンは、拡張時の単語分割とファイル名生成の点でも異なります。

このような変数を定義すると、次のようになります。

$ var="a b"

次に、これはtrueを返します。

$ [[ $var = "a b" ]]

ここでは[ab=’a b’] として展開されるため、これは構文エラーを返します。

$ [ $var = "a b" ]
bash: [: too many arguments

トークン「=」の使用法も異なります。

2つの例を作成しましょう。

$ [ abc = a?? ] # returns False
$ [[ abc = a?? ]] # return True

この動作は、組み込みの [を使用して、文字列比較を実行するためです。 一方、 [[キーワードを使用する場合、bashはパターンマッチングを実行します。

最後に、[[には=〜演算子があることに注意してください。

[[トークンを使用している間は、 =〜トークンを使用できますが、[では使用できません。

この演算子を使用すると、文字列と拡張正規表現の比較を実行できます。 演算子の右側の文字列は、拡張正規表現と見なされます。

この演算子を使用して正規表現を処理する2つの例を作成しましょう。

$ [[ Baeldung =~ .*e.* ]] && echo True || echo False 
True 
$ [[ Baeldung2 =~ ^(b|B).*g$ ]] && echo True || echo False 
False

要約すると、どちらをいつ使用するかは、何を達成したいかによって異なります。

ご覧のとおり、 [[キーワードには[およびテストビルトインよりも多くのオプションがありますが、ビルトインはPOSIXであるため、これらを使用すると、移植性が失われるのを防ぐことができます。

5. スペースについての簡単なメモ

これまで見てきたように、これらのオプションを使用して引数を評価できますが、トークン間にスペースを追加する必要がある簡単な構文に従う必要があることを忘れないでください

たとえば、この例は正常に機能します。

[ -e file ]

ただし、次のリストの各要素は次のようにはなりません。

[ -e file]
[-e file]
[-efile]

各トークンをスペースで区切らないとどうなるか見てみましょう。

$ [ 1=1] && echo True
bash: [: missing `]'

それでは、トークン [[を試してみましょう:

$ [[ 1=1]] && echo True 
bash: conditional binary operator expected 
bash: syntax error near `True'

ですから、文章を構成するときは少し注意を払う必要があります。

6. 結論

この記事では、条件式とは何か、さまざまな構成とキーワードを使用して式を作成する方法について説明しました。