Below is a "test case" ksh shell script to show examples of very minor
omissions in the ksh(1) man page regarding testing for zero length and
non-zero length. A patch for ksh.1 is below.

In the script, you'll need to manually fix the assignment of $foo for
test set #2, since sending a raw null through email is a major pain. I
have it set below as text '^@' but you'll need to replace it with a
real null (CTRL-V CTRL-@).

Some of the notes on the failures are very generous since the current
man page does mention some of the caveats but they are mentioned in
relation to comparison rather than length tests.

Sorry about the width, but the man page exceeds 72 char.

------- START KSH Script -----
#!/bin/ksh

# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# From ksh(1)
#
# [[ expression ]]
#     Similar to the test and [ ... ] commands (described later), with
#     the following exceptions:
#           ...
#           o   Field splitting and file name generation are not per-
#               formed on arguments.
#
#           o   The single argument form of test, which tests if the
#               argument has a non-zero length, is not valid; explicit
#               operators must always be used e.g. instead of [ str ]
#               use [[ -n str ]].
# ...
#
# test expression
# [ expression ]
#     test evaluates the expression and returns zero status if true,
#     if false, or greater than 1 if there was an error.  It is normal-
#     ly used as the condition command of if and while statements.
#     ...
#     string             string has non-zero length.
#     -n string          string is not empty.
#     -z string          string is empty.
#     ...
#     Note: A common mistake is to use ``if [ $foo = bar ]'' which
#     fails if parameter ``foo'' is NULL or unset, if it has embedded
#     spaces (i.e. IFS characters), or if it is a unary operator like
#     `!' or `-n'.  Use tests like ``if [ "X$foo" = Xbar ]'' instead.
#
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# http://www.opengroup.org/onlinepubs/9699919799/utilities/test.html
#
# string
#     True if the string string is not the null string; otherwise, false
#
# -n  string
#     True if the length of string is non-zero; otherwise, false.
#
# -z  string
#     True if the length of string string is zero; otherwise, false.
#
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

printf "\n**********************************************************\n";
printf "%s\n" 'Test #1: WITH $foo UNDEFINED';
printf "----------------------------------------------------------\n";
printf "#1.A.1) string has non-zero length (Should Be FALSE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#1.A.2) string has non-zero length (Should Be FALSE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'FAIL: Returned TRUE';
# else
#   printf "\t%s\n" 'PASS: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#1.B.1) string is *not* empty (Should Be FALSE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE -Noted under [ expression ]';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#1.B.2) string is *not* empty (Should Be FALSE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#1.C.1) string is empty (Should Be TRUE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#1.C.2) string is empty (Should Be TRUE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi
printf "----------------------------------------------------------\n";

# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# NOTE: You'll need to fix this since sending a raw null in email
# is a major pain.
foo='^@'
printf "\n**********************************************************\n";
printf "%s%s\n" 'Test #2: WITH $foo DEFINED as <null> 0x00' "foo='^@'";
printf "----------------------------------------------------------\n";
printf "#2.A.1) string has non-zero length (Should Be FALSE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#2.A.2) string has non-zero length (Should Be FALSE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'FAIL: Returned TRUE';
# else
#   printf "\t%s\n" 'PASS: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#2.B.1) string is *not* empty (Should Be FALSE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE -Noted under [ expression ]';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#2.B.2) string is *not* empty (Should Be FALSE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#2.C.1) string is empty (Should Be TRUE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#2.C.2) string is empty (Should Be TRUE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi
printf "----------------------------------------------------------\n";


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
foo=''
printf "\n**********************************************************\n";
printf "%s%s\n" 'Test #3: WITH $foo DEFINED as empty: ' "foo=''";
printf "----------------------------------------------------------\n";
printf "#3.A.1) string has non-zero length (Should Be FALSE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#3.A.2) string has non-zero length (Should Be FALSE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'FAIL: Returned TRUE';
# else
#   printf "\t%s\n" 'PASS: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#3.B.1) string is *not* empty (Should Be FALSE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE -Noted under [[ expression ]]';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#3.B.2) string is *not* empty (Should Be FALSE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#3.C.1) string is empty (Should Be TRUE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#3.C.2) string is empty (Should Be TRUE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi
printf "----------------------------------------------------------\n";

# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
foo=0
printf "\n**********************************************************\n";
printf "%s%s\n" 'Test #4: WITH $foo DEFINED as 0 :' "foo=0";
printf "----------------------------------------------------------\n";
printf "#4.A.1) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#4.A.2) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'PASS: Returned TRUE';
# else
#   printf "\t%s\n" 'FAIL: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#4.B.1) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#4.B.2) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#4.C.1) string is empty (Should Be FALSE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#4.C.2) string is empty (Should Be FALSE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi
printf "----------------------------------------------------------\n";


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
foo=bar
printf "\n**********************************************************\n";
printf "%s\n" 'Test #5: WITH $foo DEFINED as "bar": foo=bar';
printf "----------------------------------------------------------\n";
printf "#5.A.1) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#5.A.2) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'PASS: Returned TRUE';
# else
#   printf "\t%s\n" 'FAIL: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#5.B.1) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#5.B.2) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#5.C.1) string is empty (Should Be FALSE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#5.C.2) string is empty (Should Be FALSE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi
printf "----------------------------------------------------------\n";


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
foo='
'
printf "\n**********************************************************\n";
printf "%s\n" 'Test #6: WITH $foo DEFINED as <newline>: foo=<newline>';
printf "----------------------------------------------------------\n";
printf "#6.A.1) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE   ***FIXME***';
fi

printf "----------------------------------------------------------\n";
printf "#6.A.2) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'PASS: Returned TRUE';
# else
#   printf "\t%s\n" 'FAIL: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#6.B.1) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#6.B.2) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#6.C.1) string is empty (Should Be FALSE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE   ***FIXME***';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#6.C.2) string is empty (Should Be FALSE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi
printf "----------------------------------------------------------\n";

# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
foo=' '
printf "\n**********************************************************\n";
printf "%s%s\n" 'Test #7: WITH $foo DEFINED as <space>: ' "foo=' '";
printf "----------------------------------------------------------\n";
printf "#7.A.1) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE -Noted under [ exression ]';
fi

printf "----------------------------------------------------------\n";
printf "#7.A.2) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'PASS: Returned TRUE';
# else
#   printf "\t%s\n" 'FAIL: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#7.B.1) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#7.B.2) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#7.C.1) string is empty (Should Be FALSE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE   ***FIXME***';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi

printf "----------------------------------------------------------\n";
printf "#7.C.2) string is empty (Should Be FALSE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi
printf "----------------------------------------------------------\n";

# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
foo='this that'
printf "\n**********************************************************\n";
printf "%s%s\n" 'Test #8: WITH $foo DEFINED w/IFS: ' "foo='this that'";
printf "----------------------------------------------------------\n";
printf "#8.A.1) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE -Noted Under [ expression ]';
fi

printf "----------------------------------------------------------\n";
printf "#8.A.2) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'PASS: Returned TRUE';
# else
#   printf "\t%s\n" 'FAIL: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#8.B.1) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE -Noted under [ expression ]';
fi

printf "----------------------------------------------------------\n";
printf "#8.B.2) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE -Noted under [ expression ]';
fi

printf "----------------------------------------------------------\n";
printf "#8.C.1) string is empty (Should Be FALSE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE   ***FIXME error***';
fi

printf "----------------------------------------------------------\n";
printf "#8.C.2) string is empty (Should Be FALSE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi
printf "----------------------------------------------------------\n";


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
foo='-z that'
printf "\n**********************************************************\n";
printf "%s%s\n" 'Test #9: WITH $foo DEFINED unary: ' "foo='-z that'";
printf "----------------------------------------------------------\n";
printf "#9.A.1) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [ string ]'\n";      
if [ $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE -Noted Under [ expression ]';
fi

printf "----------------------------------------------------------\n";
printf "#9.A.2) string has non-zero length (Should Be TRUE)\n";
printf "\t'if [[ string ]]'\n"; 
printf "\tERROR -Noted under [[ expression ]]\n";
# if [[ $foo ]];
# then
#   printf "\t%s\n" 'PASS: Returned TRUE';
# else
#   printf "\t%s\n" 'FAIL: Returned FALSE';
# fi

printf "----------------------------------------------------------\n";
printf "#9.B.1) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [ -n string ]'\n";
if [ -n $foo ];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE -Noted under [ expression ]';
fi

printf "----------------------------------------------------------\n";
printf "#9.B.2) string is *not* empty (Should Be TRUE)\n";
printf "\t'if [[ -n string ]]'\n";
if [[ -n $foo ]];
then
  printf "\t%s\n" 'PASS: Returned TRUE';
else
  printf "\t%s\n" 'FAIL: Returned FALSE -Noted under [ expression ]';
fi

printf "----------------------------------------------------------\n";
printf "#9.C.1) string is empty (Should Be FALSE)\n";
printf "\t'if [ -z string ]'\n";
if [ -z $foo ];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE   ***FIXME error***';
fi

printf "----------------------------------------------------------\n";
printf "#9.C.2) string is empty (Should Be FALSE)\n";
printf "\t'if [[ -z string ]]'\n";
if [[ -z $foo ]];
then
  printf "\t%s\n" 'FAIL: Returned TRUE';
else
  printf "\t%s\n" 'PASS: Returned FALSE';
fi
printf "----------------------------------------------------------\n";

exit 0
------- END KSH Script -----


------- START ksh.1 patch -----
Index: ksh.1
===================================================================
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.129
diff -u ksh.1
--- ksh.1       28 May 2009 06:09:06 -0000      1.129
+++ ksh.1       11 Jan 2010 08:21:22 -0000
@@ -761,6 +761,8 @@
 .No \&[ Ar str No \&]
 use
 .No \&[[ -n Ar str No \&]] .
+Similarly, testing for zero length should use
+.No \&[[ -z Ar str No \&]] .
 .It
 Parameter, command, and arithmetic substitutions are performed as expressions
 are evaluated and lazy expression evaluation is used for the
@@ -4013,6 +4015,35 @@
 Use tests like
 .Dq if \&[ \&"X$foo\&" = Xbar \&]
 instead.
+.Pp
+Additionally, testing for zero length with
+.Dq if \&[ -z $foo \&]
+, or testing for non-zero length with either
+.Dq if \&[ -n $foo \&]
+, or
+.Dq if \&[ $foo \&]
+can also fail if parameter
+.Dq foo
+is
+.Dv NULL
+, or unset, or contains spaces (i.e.\&
+.Ev IFS
+characters), or contains newline characters, or contains unary operators like
+.Sq Fl n
+or
+.Sq Fl z
+or
+.Sq \&! .
+If you are not intentionally trying to evaluate multiple elements in a list,
+you can avoid these caveats if you use
+.Dq if \&[\&[ -z $foo \&]\&]
+for testing zero length, and use
+.Dq if \&[\&[ -n $foo \&]\&]
+for testing non-zero length. As noted above, the use of
+.Dq if \&[\&[ $foo \&]\&]
+is not valid, so you'll need to use the 
+.Sq Fl n
+operator.
 .Pp
 .It Xo
 .Ic time
------- END ksh.1 patch -----


-- 
J.C. Roberts

Reply via email to