web-dev-qa-db-ja.com

ifコマンドでの条件のテスト

両方のシナリオでechoステートメントが実行されている理由は何ですか?

出力it worked

#!/bin/bash

rizwan=''
if [ -n $rizwan ]; then
  echo "it worked"
fi

-n-zに置き換えます。出力がない場合は、it workedが出力されます。

#!/bin/bash

rizwan=''
if [ -z $rizwan ]; then
  echo "it worked"
fi
3
rizwan

あなたはそれを知っているかどうかはわかりませんが、明確にしましょう:[if構文の一部ではありません。つまり、if [ …if trueif falseまたはif any_commandのように動作します。ここで、[truefalseおよびany_commandはコマンドです。それらは終了ステータスを返し、これがifにとって重要です。

[が組み込み(Bashにある)の場合でも、通常のコマンドのように動作します。スタンドアロンの[実行可能ファイル(例:/usr/bin/[)もあり、POSIXで必要とされるためです。

つまり、[ -n whatever ]は、引数がほとんどない[コマンドです。はい、]は単なる引数であり、区切り文字などではありません。 [という名前のコマンドは、]が最後の引数であることを要求するだけです(これにより、コードが読みやすくなります)。

シェルが$rizwanを空の文字列に展開すると、スニペット[ -n $rizwan ]および[ -z $rizwan ]はそれぞれ[ -n ]および[ -z ]になります。 [コマンドは、コードで-n(または-z)と]の間に何かがあったことを認識していません。正確に2つの引数を取得します。どちらのテストも[ STRING ]構文として扱われます。ここで、STRING-nまたは-zです。この構文は、STRINGが空でないかどうかをテストします。 -n-zも空の文字列ではないため、テストは常に成功します。

スニペットを[ -n STRING ]または[ -z STRING ]として機能させるには、変数を二重引用符で囲む必要があります。シェルは、[ -z "$rizwan" ]を展開した後、正確に3つの引数を[に渡します。それらは-z、変数の展開された値(空の文字列であっても)、および]になります。このツールは、必要なすべての引数を取得します。

例で引用符で囲まれていない$rizwanが複数のWordに展開された場合、[は4つ以上の引数を取得します。一般に、最終的な結果は、変数の内容と[の実装によって異なります。

比較 なぜシェルスクリプトが空白やその他の特殊文字で詰まるのですか?

注意Bashの[[は異なります。これはキーワードであり、シェルパーサーと統合されており、いくつかのルールを変更し、[[]]の間の変数と引用符を実際に認識しています。 [[の代わりに[を使用した場合(したがって、]]の代わりに]を使用した場合)、コードは期待どおりに機能します。 この答え を参照してください。

[はポータブルです。

7

変数rizwanが空であるため、ifコマンドは次のようになります。

if [ -n  ]

構文[ STRING ]文字列が空(文字なし)かどうかをテストします。だからあなたの場合は[ -n ]、文字列-nは明らかに空ではありません。

4
harrymc