web-dev-qa-db-ja.com

bashの整数を比較します。単項演算子が必要です

次のコードは、

[:-ge:単項演算子が必要です

いつ

i=0

if [ $i -ge 2 ]
then
    #some code
fi

どうして?

132
Filip Ekberg

あなたの問題は、ステートメントが失敗したときに$iが空の値を持つという事実から生じます。 比較を実行するとき、変数の1つが空になる可能性がわずかでもある場合、変数を常に引用する

if [ "$i" -ge 2 ] ; then
  ...
fi

これは、シェルが変数を処理する方法が原因です。元の例を仮定します、

if [ $i -ge 2 ] ; then ...

その特定のコード行を実行するときにシェルが最初に行うことは、お気に入りのエディターのsearch&replace関数と同様に、$iの値を置換することです。したがって、$iが空であると仮定するか、または、より具体的には、$iがスペースの束であると仮定してください。シェルは、次のように$iを置き換えます。

if [     -ge 2 ] ; then ...

これで変数の置換が完了したので、シェルは比較を続行し、...失敗します。これは、-gtleftが理解できるものを何も表示できないためです。ただし、$iを引用する:

if [ "$i" -ge 2 ] ; then ...

になる:

if [ "    " -ge 2 ] ; then ...

シェルは二重引用符を確認し、実際に4つの空白を2と比較していることを認識し、ifをスキップします。

次のように、$iが空白の場合、$iのデフォルト値を指定するオプションもあります。

if [ "${i:-0}" -ge 2 ] ; then ...

これは、$i$iが未定義である代わりに、値0に置き換えます。繰り返しますが、$iが空白の束である場合、undefinedとしてカウントされず、0に置き換えられず、もう一度問題。

時間があるときに this をお読みください。シェルは多くの場合ブラックボックスのように扱われますが、ごく少数の非常に単純なルールで動作します-これらのルールが何であるかを理解すると(1つは上記で説明したように、シェルでの変数の動作方法です)、シェルは秘密はもうありません。

284
vladr

エラーメッセージから判断すると、iの値は、0ではなく空の文字列でした。

6
starblue

5セントを追加する必要があります。誰もが[または[[を使用しているようですが、それらはif構文の一部ではないことに言及する価値があります。

算術比較には、代わりに((...))を使用します。

((...))は算術コマンドで、式がゼロ以外の場合は終了ステータス0を返し、式がゼロの場合は1を返します。副作用(割り当て)が必要な場合、「let」の同義語としても使用されます。

参照: 算術式

6
Roman Newaza

スクリプトの一部は非常にうまく機能します。 ifの前に "i"に他のものを割り当てていないのですか?

よくある間違いは、角括弧の前後にスペースを残さないことです。

2