完全な答え

完全な答え

私はこれを使用しようとしています:

$ if [$a == 1] then { echo 'yes'; } fi;

しかし、エラーが発生します。

-bash: syntax error near unexpected token `}'

正しい形式は何ですか?いろいろ試してみましたが、運がありませんでした。

答え1

[bashによると、これは別の文字にすぎず、自己定義されていません。したがって[、周囲にスペースを追加する必要があります][[andを使用する方が良いかもしれません]]

そして、次のコマンドif(たとえば、コマンドです)[は、または改行文字で終わる必要があります。;

最後に、==(POSIX、FWIWではない、POSIXが好む=)数値平等ではなく、文字列平等です。

だからあなたが意味するのはおそらく次のようなものです:

if [[ $a -eq 1 ]]; then echo yes; fi

ただし、代わりに算術評価を使用できます。

if ((a == 1)); then echo yes; fi

(算術評価で上等はあり==、変数名の前に付ける必要はありません$。混乱するのはわかります。)

詳細については[help test。情報[[:ヘルプ[[(基準test)。について((help let。についてbashman bash

答え2

一般化する

使用:

if [ "$a" = 1 ]; then echo yes; fi

完全な答え

バッシュエラー:-bash:予期しないマーカー "}"の近くで構文エラーが発生しました。これはコードライターがエラーを探すように指示しようとしますが、bashは間違った場所でエラーやシグナルエラーが発生しやすいです。

実際、コードにはいくつかのエラーがあります。しかし、より単純なコード行を使用してbashが報告したエラーを再現しましょう。

$ if true then { true; } fi;
bash: syntax error near unexpected token `}'

行がわずかに変更された場合、エラーはほぼ同じ場所で報告されますが、若干異なります。

$ if true then true; fi;
bash: syntax error near unexpected token `fi'

そして、次のエラーも報告されます。

$ if true; then; true; fi;
bash: syntax error near unexpected token `;'

これは、必須構文(マニュアルからコピー)が次のようになるために発生します。

if list; then list; fi;

list1つ以上の単純コマンド(またはパイプまたは複合コマンド)が次に終わる場所はどこですか?新しいチームまたはセミコロン。通常、改行文字はセミコロンで置き換えることができ、その逆も可能です。

動作します(構文エラーは報告されません)。

if   true;   then   true;   fi

これはまた働きます:

if     true
then   true
fi

または:

if echo start; true; then echo decision; true; echo next; fi;

または改行および/またはセミコロンの他の変形。

もちろん、最後のセミコロンは必須ではありませんが、禁止されていません。

また、bashから単語(トークン)で区別してテストとして理解するには(通常)スペースが必要です[]

if [ $a == 1 ]; then { echo 'yes'; } fi;       # still subtly incorrect.

"$a"ただし、変数の拡張も引用符()で囲む必要があります。これはbashでは機能しますが、他のいくつかのシェルでは機能しない可能性があるため、技術的に引用を必要としない内部単一を使用する必要があります==(害はありませんが)。 1つの単純なコマンドブレースが必要ないので、より良いバージョンになります。=[ ]'yes'{ }

if [ "$a" = 1 ]; then echo yes; fi

または bash/ksh/zsh を使用することを選択した場合[[ ]]:

if [[ $a == 1 ]]; then echo yes; fi

=最後にorを使ったテストは==数値比較ではなく文字列比較な+1のでいいえ1同じ価値を持っているにもかかわらず。数値テストを実行するには、を使用できます-eq

答え3

[ifなどwhileの他のコマンドと同様に、Bashのコマンドです。マニュアルページを注意深く見てみると、次のことがわかります。

$ man [
NAME
       bash, :, ., [, alias, bg, bind, break, builtin, caller, cd, command, .....

次の例を見ると、これが実際のコマンドであることがわかります。

$ type -a [
[ is a shell builtin
[ is /usr/bin/[

最初の結果は[Bashの組み込みバージョンです。 2番目は[GNU coreutilsに含まれているバージョンです。

Fedoraでは、そのRPMが属するRPMを確認できます。

$ rpm -qf /usr/bin/[
coreutils-8.5-7.fc14.x86_64

したがって、正しく解析するために、すべてのコマンドの周りにスペースがあることを確認する必要があります。

この方法:

$ if [$a == 1] ...

これと同じ:

$ lsblah
bash: lsblah: command not found...

ls解析できるように空白にバッファされていないため、コマンドは正しく解析されません。

答え4

if [ "$a" = 1 ]; then echo yes; fi

または

if test "$a" -eq 1 ; then echo yes; fi

または

if /usr/bin/test "$a" -eq 1;then echo yes;fi

シェルはセミコロンでテストするためにコマンドラインを切り取ります(その後、テストされたコマンドラインに引数を追加します - 組み込みでない場合はargc / argv)。

しかし、これはうまくいきません。

if test "$a"-eq 1; then echo yes; fi

シェルはテストするパラメータをどこで分割する必要がありますか?したがって、文字列 '+1-eq 1'は分割されません。

これにより、テストが別々のプログラムであることが明らかになります。

 sh:~$ LANG=C sh -c 'a=+1 ; if test "$a"-eq 1 ; then echo yes ; fi'
 sh: 1: test: +1-eq: unexpected operator

これとは対照的に:

 sh:~$ LANG=C sh -c 'a=+1 ; if /usr/bin/test "$a"-eq 1;then echo yes;fi'
 /usr/bin/test: missing argument after '1'

さて、テスト中の同じパラメータに対して異なるエラーメッセージがあります。

関連情報