On Mon, Jan 11, 2010 at 1:01 AM, J.C. Roberts <list-...@designtools.org> wrote: > 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-@).
NULs are always silently dropped from strings by the shell, so test this part of your script duplicates the part where foo is the empty string. > 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. ... > @@ -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 \&]] . Given the context, this seems unnecessary. Currently it reads: 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 ]]. So, the test for "not zero length" that works with [...] but not [[...]] is [ ! str ] ...which can be translated using the rule already documented to get [[ ! -n str ]] > +.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.\& ... (Two nits with your manpage source: 1) Always start sentences at the beginning of a line, 2) Commas and periods should be at the end of the line, albeit *preceeded* with a space if the line has a formatting macro. For example: .Dv NULL , ) I'm not entirely convinced this change should be made, in part because it's too narrow. Problems with arguments to 'test' that are empty or contain whitespace is not restricted to -z and -n and can just as well hit the file tests. Why stop there? Programs other than 'test' are affected too! And don't forget to pass '--' to programs to stop option parsing when the first positional argument is from a variable. And use arrays when you need to store multiple values that may contain whitespace. And... Then again, 'test' does seem to be the place where people first slam into this. <mumble> (As a side-note, both the existing "Note" and your proposed addition are wrong about the unquoted constructs having problems when the variable's value is '!' or '-n'. It's only if it's unset, empty, or contains characters from $IFS that a problem occurs. Some other OSes (*cough* Solaris *cough*) have versions of /bin/sh that can choke on those, but OpenBSD's follows the rules there.) > +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. While directing people to use [[...]] might be okay for the ksh(1) manpage, it won't fly for the sh(1) manpage. Simply saying "quote your arguments!" on both would be simpler. Philip Guenther