Return to BSD News archive
Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!munnari.OZ.AU!news.ecn.uoknor.edu!news.wildstar.net!newsfeed.direct.ca!portc01.blue.aol.com!portc02.blue.aol.com!news.bbnplanet.com!cpk-news-hub1.bbnplanet.com!news.mindspring.com!tarush From: tarush@mindspring.com (Tom Rush) Newsgroups: comp.unix.bsd.freebsd.misc Subject: /bin/test bug? Date: 24 Dec 1996 04:49:19 GMT Organization: Rush Co. Lines: 43 Message-ID: <59nncf$m8c@camel0.mindspring.com> NNTP-Posting-Host: user-168-121-119-56.dialup.mindspring.com Xref: euryale.cc.adfa.oz.au comp.unix.bsd.freebsd.misc:33041 There appears to be a problem with /bin/test and the -a and -o operators. The problem occurs when using the form ' test "string" ', which according to the man page, returns true if "string" is not a null string. If testing to see if a shell variable is unset or null, e.g. ' test "$VAR1" ', the shell passes a null string if VAR1 is unset, and test returns 1, as expected. However, if both VAR1 and VAR2 are unset, the form ' test "$VAR1" -o "$VAR2" ' returns 0, not 1, as expected. ' test "$VAR1" -a "$VAR2" ' also returns 0. The TEST.csh script in the source checks this (and fails); the TEST.sh script in -current does not check for this. In looking at the source, the problem is not hard to find. The comments in expr_operator() under case AND1 and OR1 say that "these operands are mostly handled by the parser". But in this situation, the expression is never touched by the parser; it has been passed to posix_binary_op by the special case code at the top of main(). The solution would appear to be to break out the "andor_op" case in the main() code, so it will continue on to the parser (see patch). This same method is used just a few lines down from this point for a different case. This gives the results as described in the man page. ---------------- --- test.c.orig Sat Dec 14 06:11:34 1996 +++ test.c Mon Dec 23 22:47:13 1996 @@ -157,7 +157,7 @@ ret_val = posix_unary_op(&argv[1]); if (ret_val >= 0) return (!ret_val); - } else { + } else if (lookup_op(argv[2], andor_op) < 0) { ret_val = posix_binary_op(&argv[1]); if (ret_val >= 0) return (ret_val); ---------------- -- Tom Rush tarush@mindspring.com