155

I am trying to run the following shell script which is supposed to check if a string is neither space nor empty. However, I am getting the same output for all the 3 mentioned strings. I have tried using the "[[" syntax as well but to no avail.

Here is my code:

str="Hello World"
str2=" "
str3=""

if [ ! -z "$str" -a "$str"!=" " ]; then
        echo "Str is not null or space"
fi

if [ ! -z "$str2" -a "$str2"!=" " ]; then
        echo "Str2 is not null or space"
fi

if [ ! -z "$str3" -a "$str3"!=" " ]; then
        echo "Str3 is not null or space"
fi

I am getting the following output:

# ./checkCond.sh 
Str is not null or space
Str2 is not null or space
Jens
  • 69,818
  • 15
  • 125
  • 179
Shubhanshu Mishra
  • 6,210
  • 6
  • 21
  • 23

6 Answers6

178

You need a space on either side of the !=. Change your code to:

str="Hello World"
str2=" "
str3=""

if [ ! -z "$str" -a "$str" != " " ]; then
        echo "Str is not null or space"
fi

if [ ! -z "$str2" -a "$str2" != " " ]; then
        echo "Str2 is not null or space"
fi

if [ ! -z "$str3" -a "$str3" != " " ]; then
        echo "Str3 is not null or space"
fi
dogbane
  • 266,786
  • 75
  • 396
  • 414
  • Thanks a lot, it works. But I wonder why the assignment doesn't use a space whereas a comparison does. – Shubhanshu Mishra Nov 22 '12 at 09:44
  • 7
    ^^It's syntax. The first word on the command line is the command & subsequent ones are arguments. `var=value [command [args]]` is the syntax, in which a variable is assigned value. for comparison, `[` (`/usr/bin/[`) is the command & it requires var1, != & var2 to be 3 separate arguments. var1!=var2 is a single argument. – anishsane Nov 22 '12 at 09:48
89

For checking the empty string in shell

if [ "$str" == "" ];then
   echo NULL
fi

OR

if [ ! "$str" ];then
   echo NULL
fi
Wok
  • 4,956
  • 7
  • 42
  • 64
RajeshKashyap
  • 929
  • 5
  • 3
  • 27
    The shell's string equality operator is `=`. The `==` is a non-portable hack invented by shell authors to mess up the minds of young programmers. – Jens Apr 21 '17 at 20:13
36

Another quick test for a string to have something in it but space.

if [[ -n "${str// /}" ]]; then
    echo "It is not empty!"
fi

"-n" means non-zero length string.

Then the first two slashes mean match all of the following, in our case space(s). Then the third slash is followed with the replacement (empty) string and closed with "}". Note the difference from the usual regular expression syntax.

You can read more about string manipulation in bash shell scripting here.

elomage
  • 4,334
  • 2
  • 27
  • 23
21

In case you need to check against any amount of whitespace, not just single space, you can do this:

To strip string of extra white space (also condences whitespace in the middle to one space):

trimmed=`echo -- $original`

The -- ensures that if $original contains switches understood by echo, they'll still be considered as normal arguments to be echoed. Also it's important to not put "" around $original, or the spaces will not get removed.

After that you can just check if $trimmed is empty.

[ -z "$trimmed" ] && echo "empty!"
hyde
  • 60,639
  • 21
  • 115
  • 176
  • 3
    In bourne shell I end up with "--" as the value of trimmed. – Sridhar Sarnobat Mar 27 '17 at 05:17
  • According to [this post](https://unix.stackexchange.com/questions/11376/what-does-double-dash-mean), echo does not interpret -- to mean the end of options. In my Bash shell, I get the same result as Sridhar Sarnobat – Mr.C Aug 16 '20 at 02:08
10

To check if a string is empty or contains only whitespace you could use:

shopt -s extglob  # more powerful pattern matching

if [ -n "${str##+([[:space:]])}" ]; then
    echo '$str is not null or space'
fi

See Shell Parameter Expansion and Pattern Matching in the Bash Manual.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
2
[ $(echo $variable_to_test | sed s/\n// | sed s/\ //) == "" ] && echo "String is empty"

Stripping all newlines and spaces from the string will cause a blank one to be reduced to nothing which can be tested and acted upon

  • I think the `g` flag is missing in sed commands, to change *all* occurences: `[ $(echo $variable_to_test | sed s/\n//g | sed s/\ //g) == "" ] && echo "String is empty"` – Rémi.B Mar 26 '21 at 08:28