I'm checking the following code:
#!/usr/bin/env bash
set -o errexit
set -o nounset
if [ -n "$@" ]; then
echo "not null";
else
echo "null";
fi
This means that if I call my script like so ./my-script.sh parameter
it should result with not null
and when called like so ./my-script.sh
it should say null
.
Documentation says that -z
means string is null, that is, has zero length
and -n
means that string is not null
.
For some reason my code always claims that $@
is not null.
Why is that?
When I replace -n
with -z
and swap the content like so:
if [ -z "$@" ]; then
echo "null";
else
echo "not null";
fi
then it works correctly.
"$@"
isn't a single string: It expands to a variable number of items. If, say, you have ./yourscript one two three
, then [ -n "$@" ]
becomes [ -n one two three ]
, which isn't valid syntax. Or if you have zero arguments, it becomes [ -n ]
, which is true. ([ -z ]
is also true, because [ anything ]
checks whether anything
is an empty string, and "-z"
is a non-empty string, just as "-n"
is).
If you want to know if "$@"
is empty, check $#
instead, which will tell you how many items it contains.
if [ "$#" -eq 0 ]; then
echo "null"
else
echo "not null"
fi