[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Testing Whether $@ Is Empty Or Null
From: |
Greg Wooledge |
Subject: |
Re: Testing Whether $@ Is Empty Or Null |
Date: |
Tue, 11 Oct 2022 10:35:28 -0400 |
On Tue, Oct 11, 2022 at 10:16:21AM -0400, Chet Ramey wrote:
> On 10/11/22 1:00 AM, Jessie Saenz wrote:
> > bash version = 5.1.16(1)-release
> >
> > I do not understand why the following statement returns 0 despite no
> > arguments given to script:
> >
> > [ -n "$@" ] && echo true
>
> `[' is a builtin, so the arguments undergo word expansion before it's
> invoked.
>
> "$@" expands to nothing when there are no positional parameters.
>
> The command ends up being `[ -n ]', which is true because there is one
> non-null argument to `['.
And of course, the command will blow up with an error if there are a
bunch of arguments.
unicorn:~$ set -- one two three
unicorn:~$ [ -n "$@" ]
bash: [: too many arguments
Now, that's the technical answer. I like to look at the underlying
reason for the question.
If you're trying to detect whether your script/function was called with
no arguments (maybe so you can print a usage message), you should be
using the $# special parameter instead. This contains the number of
arguments. Like so:
if test "$#" = 0; then
echo "I was called without any arguments."
fi
Of course, you can use other test variants, like [ "$#" = 0 ], or
[[ $# == 0 ]], or (($# == 0)) if you prefer.
If what you actually want to know is whether your script/function was
called without any NON-EMPTY arguments (i.e. empty arguments don't count),
then you'll need a loop. It's hard for me to imagine why you might
want such a thing, but it's the best guess I can make about your Subject:
header.
hasarg=0
for arg; do
if test "$arg"; then
hasarg=1
break
fi
done
if ((hasarg)); then
echo "I was called with at least one non-empty argument."
fi