if条件の括弧:空白なしで構文エラーが発生するのはなぜですか?


17

次のスクリプトを使用して、1年の2日間の開始時にスクリプトを実行するときに2日前に移動し、また毎月1日と2日目をチェックして2日前に移動します。

if [$month="01"] && [$day="01"];
then
    date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
if [$month="01"] && [$day="02"];
then
         date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
   if [ $day = "01" ];
then
    date="$last_month/$yes_day/$year"
            fulldate="$year$last_month$yes_day"
else
        if [ $day = "02" ];
then
    date="$last_month/$yes_day/$year"
        fulldate="$year$last_month$yes_day"
else
    date="$month/$yes_day/$year"
        fulldate="$year$month$yes_day"
                fi
               fi
              fi
fi

しかし、私の悪いは、以下のエラーメッセージを取得しています

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found

1
与えられた答えは正しいです。後に空白が必要です[。さらに、elifステートメントを調べます。物事をきれいにするのに役立ちます。また、ifステートメントの後のセミコロンは必要ではありませんが、不正確ではなく、単に奇妙です。
ショーンJ.ゴフ

@ ShawnJ.Goff次の行(if [ ... ]; then)を連結する場合に必要なので、それほど珍しいことではありません。
goldilocks

@goldilocks、はい、それは私の好みのスタイルです。珍しいのは、彼がそうしていないからです。
ショーンJ.ゴフ

回答:


27

[はメタ文字でも制御演算子でもない(予約語でもない、の場合も同じ])ため、周囲に空白が必要です。それ以外の場合は、シェルコマンドを「見る」[01=01]コマンドの代わりに[別のパラメータを使用して01=01、と]。各演算子とオペランドは[コマンドに対する個別の引数である必要があるため、演算子の周りにも空白が必要です。

if [ "$month" = "01" ]

[$month="01"]は、$monthまたはの文字のいずれかに一致するワイルドカードパターン"01です。一致しない場合は、そのままにします。

閉じ括弧の後にセミコロンがある場合、セミコロンは常に別のトークンの一部であるため、その前にスペースは必要ありません。

if [ "$month" = "01" ]; then

同じことがbash(およびkshとzsh)の二重括弧構文にも当てはまります。

複数の条件

条件を組み合わせるには2つの方法があります。

  1. 以内に [

  2. または[と組み合わせた個別のコマンド&&||

括弧でグループ化すると、おそらく内で簡単です[

if [ "$month" = "01" -a "$day" = "01" ] # -a for and, -o for or

if [ "$month" = "01" ] && [ "$day" = "01" ]

最初のものは信頼性が低いため避けるべきです(例えばで試してくださいmonth='!')。奇妙な可変コンテンツの問題は、最初に安全な文字列(ある場合)を使用することで回避できます。または[[/の]]代わりに[/ を使用して]

if [ "01" = "$month" -a "01" = "$day" ]

月の値==日の値if [$ month = "01"] && [$ day = "01"];のように、ifで2つの条件を一致させる方法 01 && 01がtrueの場合、条件の下に印刷したり、他のステートメントに移動し期待してい
Kumar1を

@AshokSanganahalli私は答えを拡張しました。
ホークレイジング

1
[とき-a/ -o使用されていないことは、常にPOSIX互換のシェルと信頼性があります。-a/-oover を使用することには何の利点もありません&&/||。私は間違いなくその使用を思いとどまらせるでしょう。[[POSIX ではないことに注意してください。
ステファンシャゼル14年

4

別の書き方:

case $month:$day in
  (01:0[12])
    date="$last_month/$yes_day/$last_year"
    fulldate="$last_month/$yes_day/$last_year"
    ;;
  (*:0[12])
    date="$last_month/$yes_day/$year"
    fulldate="$year$last_month$yes_day"
    ;;
  (*)
    date="$month/$yes_day/$year"
    fulldate="$year$month$yes_day"
esac

1
caseステートメントの+1 。複数あるelif場合は、おそらくを使用する必要がありますcase
HalosGhost 14年

-1

だから、これはあなたの答えです:

if [ $var1 == $var2 ];
 then
    echo "bla bla"
fi

そのため、角括弧と変数/値の間に「スペース」を入れる必要があります。


というのは、スクリプトが1年の2日間の開始時に2日前に戻るように要求し、また毎月1日と2日目をチェックし、2日前に戻ることを意味している場合[$ month = "01"] && [$ day = "01"]月 "01"と最初の日 "01"がtrueに一致し、それから移動するか、他の条件に移動すると
仮定

1
@AshokSanganahalli:あなたは角括弧と値の間に「空白」を持っていないので、私はこれが関係しているのか分からないが、あなたのIF条件が機能していません
ネベン

@AshokSanganahalli通常、少なくともヒントを試してみることなく、明らかにより良い理解を持っている人々からの修正に異議を唱えることは、あなたのスキルレベルの人々にとっては良い考えではありません。推測が正しければ、ここで質問する必要はないでしょうか?
ホークレイジング

4
-1引用符で囲まれていない変数および==標準の代わりの使用=
ステファンシャゼル14年

2
質問にはbashタグは付いていません。標準の[別名testコマンドの等値比較演算子は=です。[テストの場合、割り当てを行わないので、明確にする必要はありません。一部の[実装で==は、標準を超える拡張機能としてサポートしていますが、すべてではありません。Bourneシェル、ash's、posh' [sまたは/bin/[一部のシステムのインスタンスはそうではありません。==追加されたksh私は、その新規に同じオペレータとの整合性のために仮定していない、(( ... ))(それが標準の両方を持つ=と==が、)構築
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.