"test -n && echo notempty" は "notempty" を出力します。これが予想される動作ですか?

"test -n && echo notempty" は "notempty" を出力します。これが予想される動作ですか?

次の行を実行するとき

test -n && echo not empty

「空ではない」を印刷します。これは、空の変数があり、nullでないことをテストし、値を引用することを忘れたときに発生します。

VAR=
test -n  $VAR  && echo wrong 1
test -n "$VAR" && echo wrong 2

これが予想される動作ですか?

答え1

はい、これは予想される動作です。 1つの引数だけに渡されると、test長さの確認が行われます。からman bash

test と [ 引数の数に応じて、一連の規則を使用して条件式を評価します。

引数0:式が偽です。

パラメーター 1: パラメーターが空でない場合のみ、式は true です。

つまり、本質的には同じですtest foo-n文字列として使用されます。

答え2

test -nはい一見の証拠-nパラメータが必須であるため、形式が正しくありません。いくつかの歴史的実装では、これを構文エラーとして扱い、ゼロ以外の状態を返したと思います。しかし、21世紀に遭遇する可能性があるすべてのシェルでは、動作は明確に定義されています(以下を介して)。POSIX、既存の規則に従います):test引数が1つしかない場合、その引数がnullでない場合にのみtrueです。

引用符を省略すると、null以外の一部の値に対してテストがfalseになることがあります$VAR。ワイルドカード文字がある場合は、エラーメッセージを印刷することもできます$VAR

VAR='foo -a -z bar'; test -n $VAR || echo "true... and false is false"
VAR='= n-'; test -n $VAR || echo "this is an equality test"
VAR='*'; test -n $VAR || echo "you may or may not see this depending on what files are in the current directory"

test -z $VARまた壊れた。

Ksh、bash、zshには、[[ … ]]既存のプログラムtest[ユーティリティプログラムを模倣した条件付き構造があります。とは異なり、外部ユーティリティやシェル構文の一部である解析などの組み込み[ユーティリティです。[[ … ]]内部にはワードセパレータやワイルドカードはありません[[ … ]][[ -n $VAR ]]問題ありません(スクリプトがashなどの他のシェルで実行されていない限り)。

答え3

また確認してください[[ ... ]]。次のように動作しません。

[[ -n $VAR ]] && echo wrong 3
[[ -n "$VAR" ]] && echo wrong 4

答え4

次のようにすると表示されるようです。

VAR=
test -n $VAR && echo helloworld

引数が存在しないかのように処理します。

test -n && echo helloworld

そして何らかの理由で引数が与えられない場合は、常に後でコマンドを実行します(例:helloworldを表示)。私はこれを別の単項演算子に試してみましたが、同じことをしました:

FILENAME=
test -f $FILENAME && echo helloworld

予想される動作を得るには、次の主張を引用する必要があると思います。

VAR=
test -n "$VAR" && echo helloworld
FILE=
test -f "$FILE" && echo helloworld

上記の内容は画面には何のメッセージも表示されません。

これが予想される動作かどうかは何ですか?ドキュメントのどこにも見つかりませんが、かなり繰り返し可能で一貫性があるようです。

関連情報