[ ! -z "$@" ] considered harmful

Issue #135 closed
Lennart Lövstrand created an issue

[I wrote this comment to Issue #129, but I guess Bitbucket doesn’t automatically notify bug owners when there’s new activity on an already resolved bug, so I’m reposting it as a new issue instead.]

Hi, I realize that this bug [Issue #129] already has been resolved, but I’d like to add a few comments to explain why it works as it does and perhaps convince you that there may be a better way to solve the problem. The reason why [ -n "$@" ] succeeds (i.e. returns true) when there are no arguments is because "$@" doesn’t expand into the empty string – it expands into “nothing.” That is, [ -n "$@" ] turns into [ -n ], not [ -n "" ]. Since [ -n ] is not a valid test expression, the result (AFAIK) is undefined. In this case it turned out to be true, but it might as well have been false in another the implementation.

What I presume you indented to do is [ -n "$*" ]. That does indeed turn into [ -n "" ] when there are no arguments and thus evaluates to false. However, since “$*” may do a lot of unnecessary string concatenations and also doesn’t account for the case when someone explicitly supplies an empty string as an argument, an arguably better way to test for the actual absence of arguments is to do [ $# -eq 0 ], i.e. count the arguments and see if the result is zero. You could also do [ $# = 0 ] if you prefer, although that technically is comparing two strings (“0”) instead of numeric values.

I’d suggest re-fixing this bug as [ ! -z "$@" ] expands into [ ! -z ], which also is an invalid test expression, but just so happens to return false. Let me know if you’d like me to provide you with a diff or submit a pull request, I’m preparing one for another bug anyway and could make one for this case too.

BTW: My apologies if I’m being overly explanatory. You probably know this already, but just didn’t think of it. I know, it’s really easy to overlook.

Comments (2)

  1. Kevin Zheng
    • changed status to open

    Thank you for the explanation; I really didn't know and learned something new today!

    I'd appreciate it if you could submit a patch. Thanks again.

  2. Log in to comment