15
function wtf() {
  echo "\$*='$*'"
  echo "\$@='$@'"
  echo "\$@='"$@"'"
  echo "\$@='""$@""'"
  if [ -n "$*" ]; then echo " [ -n \$* ]"; else echo "![ -n \$* ]"; fi
  if [ -z "$*" ]; then echo " [ -z \$* ]"; else echo "![ -z \$* ]"; fi
  if [ -n "$@" ]; then echo " [ -n \$@ ]"; else echo "![ -n \$@ ]"; fi
  if [ -z "$@" ]; then echo " [ -z \$@ ]"; else echo "![ -z \$@ ]"; fi
}

wtf

生産する

$*=''
$@=''
$@=''
$@=''
![ -n $* ]
 [ -z $* ]
 [ -n $@ ]
 [ -z $@ ]

7.3 その他の比較演算子はfor allの逆であるべきだと示している[-n $@]ので、それは false であるべきだと私には思えます。[ -n "$X" ][ -z "$X" ]$X

-z

文字列がヌル、つまり長さがゼロ

String=''   # Zero-length ("null") string variable.

if [ -z "$String" ]
then
  echo "\$String is null."
else
  echo "\$String is NOT null."
fi     # $String is null.

-n

文字列がヌルではありません。

-nテストでは、文字列をテスト ブラケット内で引用する必要があります。引用符で囲まれていない文字列を とともに使用する! -zか、引用符で囲まれていない文字列だけをテスト ブラケット内で使用しても (例 7-6 を参照)、通常は機能しますが、これは安全でない方法です。テスト済みの文字列は常に引用符で囲みます。[1]

が特別であることは知っ$@ていますが、ブール否定に違反するほど特別であることは知りませんでした。ここで何が起きてるの?


$ bash -version | head -1
GNU bash, version 4.2.42(2)-release (i386-apple-darwin12.2.0)

実際の数値の終了コードは、すべて1または次0のとおりです

$ [ -n "$@" ]; echo "$?"
0
4

2 に答える 2

18

$@が空の場合"$@"、空の文字列に展開されません。完全に削除されます。だからあなたのテストはそうではありません

[ -n "" ]

むしろ

[ -n ]

Now-nは演算子ではなく、空ではない文字列であり、常にtrueとしてテストされます。

于 2013-03-04T17:05:47.990 に答える
3

"$@"あなたが期待することをしません。の別の形式ではなく"$*"、現在のスクリプトに渡された引数の引用符付きリストに展開されます。

引数がない場合は、何も展開されません。2 つの引数aとがある場合、にb c展開されます"a" "b c"(つまり、引数に空白が保持されます)。"$*""a b c"$*a b c

于 2013-03-05T08:22:26.860 に答える