💻

bashのif文における -z -n オプション

2023/03/05に公開
9

オプション

オプション 説明
-n 文字列が空でなければtrue
-z 文字列が空であればtrue

string=""
if [ -z "$string" ] ; then
  echo "empty";
fi

"$string"は空文字列なので、emptyが表示される。

string="hoge"
if [ -n "$string" ] ; then
  echo "not empty"
fi

"$string"は空文字列ではないのでnot emptyが表示される。

補足

[ ] の記法はtestコマンドの書き換えです。

testコマンドについてはこちらの記事で解説しています。

if [ -n "hoge" ] ; then

if test -n "hoge"; then

と同じ意味になります。

GitHubで編集を提案

Discussion

ko1nksmko1nksm

{} の使い方を間違えています。
正しく動作していないので ${string}"$string" に変更してください。

あかつかあかつか

ご指摘ありがとうございます。
私の力不足でご指摘の意図を完全に理解できていないと感じておりますので、質問させてください。

まず私の環境は以下の通りです。

GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin22)
Copyright (C) 2007 Free Software Foundation, Inc.

上記の環境では、以下のように動作しました。

$ VAR=hoge
$ echo ${VAR}
hoge

その上でご指摘の内容に関してですが、変数を区切るわけでもないのにbracesを使うのが良くないという意味のご指摘でしょうか?それとも、文字通り正しく動作しないという意味でしょうか?
(いずれにせよよくないと思ったので修正はさせていただきます。正しく意図を理解した上で修正したいと考えております🙇‍♂️)

参考にさせていただいたURLです。
https://qiita.com/yohm/items/3527d517768402efbcb6#braces-

まだまだ経験が浅く、頓珍漢な質問になっていたら申し訳ありません。

ko1nksmko1nksm

正しく動いていないことは、以下の動作確認をすればわかると思います。

if [ -n ${string} ] ; then
  echo "not empty"
fi

それはそれとして一つ疑問なのですが、必要な "..." を書かないというのは、シェル言語の仕様を知らないものとして理解できるのですが、なぜこのケースでは必要ない {...} をわざわざ書いたのでしょうか? 面倒なだけだと思うのですが。

あかつかあかつか

ありがとうございます。

string=""
if [ -n ${string} ] ; then
  echo "not empty"
fi

で not empty となり正しく動作しないことを理解しました。

不要な{...}をわざわざ書いてしまったのは、おそらく${foo}barなど色々なパターンで試してみているうちに消し忘れてしまったためだと思います。なので、ご指摘の通り、面倒なだけの記述になってしまいました。

読者に誤解を与えないよう、記事の内容には気をつけたいと思います。
今回はご指摘をいただきありがとうございました。

あかつかあかつか

さらに調べて、ようやく理解したかと思います。

$VAR="aaa"とした場合、文字列としての"$VAR"は nonzero length string だが、変数としての$VARは nonzero length string ではないということでしょうか。

ko1nksmko1nksm
string=""
[ -n $string ]

[ -n ]
または
[ "-n" ]

のように解釈されるという話です。

あかつかあかつか

ありがとうございます。返信が遅くなりすみません。

[ "-n" ]と解釈された場合、終了コードが0になるのは理解できました。

なぜそのように解釈されるのかと[ -n ]の場合に終了コードが0になる理由が今ひとつ理解できません…
もう少し調べてみようと思います!

ご親切にありがとうございました。

ko1nksmko1nksm

単純に [-n] という単語が並んでいるので [ -n ] です。

[] の間に1文字以上の長さの(一つの)単語がある場合に終了コードが0になるのは [ コマンドの仕様です。

あかつかあかつか

ありがとうございます!理解したかと思います。
[ -n ]の場合は引数がSTRINGの場合で解釈されて、終了コードが0になるということなんですね。

String operators:
    
        -z STRING      True if string is empty.
    
        -n STRING
        STRING         True if string is not empty.