私が最近行ったテストでは、次のbash
コマンドの出力について質問がありました。
var=; [ -n $var ]; echo $?; [ -z $var ]; echo $?
結果はとで0
あり0
、両方の単項演算子の戻りコードにエラーがなかったことを示しています。これは、 (空)と「非ヌル」(空ではない)の$var
両方に解決されることを意味します、正しいですか?null
これはどのように可能ですか?
私が最近行ったテストでは、次のbash
コマンドの出力について質問がありました。
var=; [ -n $var ]; echo $?; [ -z $var ]; echo $?
結果はとで0
あり0
、両方の単項演算子の戻りコードにエラーがなかったことを示しています。これは、 (空)と「非ヌル」(空ではない)の$var
両方に解決されることを意味します、正しいですか?null
これはどのように可能ですか?
いいえ、それは修復不可能なほど[
壊れていることを意味します。どちらの場合$var
も、 は何も評価されず、コマンドは単純に[ -n ]
と[ -z ]
それぞれ実行され、どちらも true になります。変数自体の値をテストする場合は、適切に処理されるように引用符で囲む必要があります。
$ var=; [ -n "$var" ]; echo $?; [ -z "$var" ]; echo $?
1
0
$varを囲む必要があります。
$ [ -n "$var" ]; echo $?
1
閉じ角かっこは単なる構文糖衣であることに注意してください。必要ありません。それはあなたのラインを意味します:
$ [ -n $var ]; echo $?
($ varが空であるため)に展開されます:
$ [ -n ]; echo $?
上記の質問:「文字列']'は空ではありませんか?」そして答えはイエスです。
確かに驚くべきことです。bashism[[
構文で同じことを試してみる1
と0
、結果としてとが得られます。これはバグだと思います。
var=; [[ -n $var ]]; echo $?; [[ -z $var ]]; echo $?
または、Ignacioが指摘しているように、そして実際、私は常に直感的に、防御的なコーディングと引用を行ってきました。
var=; [[ -n "$var" ]]; echo $?; [[ -z "$var" ]]; echo $?
[
組み込みであるため、このように動作するのは私にとって驚くべきことです。
$ type [
[ is a shell builtin
ちょっとしたテストをしただけで、システムコマンド[
はビルトインと同じように壊れた方法で動作します。したがって、おそらく互換性のためにバグがあります:
var=; /usr/bin/\[ -n $var ]; echo $?; /usr/bin/\[ -z $var ]; echo $?