169

I have a shell script where we have following lines if [ -z "$xyz" ] and if [ -n "$abc" ], but I am not sure what their purpose is. Can anyone please explain?

Barun
  • 2,336
  • 20
  • 23
user3173953
  • 1,799
  • 2
  • 11
  • 3

3 Answers3

210

You can find a very nice reference for bash's operators here. If you are using a different shell, just search for <my shell> operators and you will find everything you need. In your particular case, you are using:

-n
   string is not null.

-z
  string is null, that is, has zero length

To illustrate:

$ foo="bar";
$ [ -n "$foo" ] && echo "foo is not null"
foo is not null
$ [ -z "$foo" ] && echo "foo is null"
$ foo="";
$ [ -n "$foo" ] && echo "foo is not null"
$ [ -z "$foo" ] && echo "foo is null"
foo is null
terdon
  • 234,489
  • 66
  • 447
  • 667
  • 14
    If you are having trouble getting `-n` to work, it could be because you are following some bad guides on the web (for example [GeeksforGeeks](https://www.geeksforgeeks.org/string-operators-shell-script/) or [TutorialsPoint](https://www.tutorialspoint.com/unix/unix-string-operators.htm)) which do not quote the variables. This answer, and the guide linked here, correctly quote it. **If you use `-n` without quoting, it will tell you that it's not empty even when it is!** @terdon, thanks a lot! – Fabio says Reinstate Monica Oct 24 '20 at 06:01
15

To extend terdon's answer, I found that Unix / Linux - Shell Basic Operators on Tutorials Point also includes file-related operators (as well as other useful ones).

-b file     Checks if file is a block special file; if yes, then the condition becomes true.    [ -b $file ] is false.
-c file     Checks if file is a character special file; if yes, then the condition becomes true.    [ -c $file ] is false.
-d file     Checks if file is a directory; if yes, then the condition becomes true.     [ -d $file ] is not true.
-f file     Checks if file is an ordinary file as opposed to a directory or special file; if yes, then the condition becomes true.  [ -f $file ] is true.
-g file     Checks if file has its set group ID (SGID) bit set; if yes, then the condition becomes true.    [ -g $file ] is false.
-k file     Checks if file has its sticky bit set; if yes, then the condition becomes true.     [ -k $file ] is false.
-p file     Checks if file is a named pipe; if yes, then the condition becomes true.    [ -p $file ] is false.
-t file     Checks if file descriptor is open and associated with a terminal; if yes, then the condition becomes true.  [ -t $file ] is false.
-u file     Checks if file has its Set User ID (SUID) bit set; if yes, then the condition becomes true.     [ -u $file ] is false.
-r file     Checks if file is readable; if yes, then the condition becomes true.    [ -r $file ] is true.
-w file     Checks if file is writable; if yes, then the condition becomes true.    [ -w $file ] is true.
-x file     Checks if file is executable; if yes, then the condition becomes true.  [ -x $file ] is true.
-s file     Checks if file has size greater than 0; if yes, then condition becomes true.    [ -s $file ] is true.
-e file     Checks if file exists; is true even if file is a directory but exists.  [ -e $file ] is true.
JDQ
  • 265
  • 2
  • 7
12

man test or man [ will give you all the options to test command. In this case, -n is testing to see if the content of $abc has a non-zero length and -z is testing to see if the content of $xyz is a zero-length string.

doneal24
  • 4,910
  • 2
  • 16
  • 33
  • man [ doesn't work for me in GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu). But +1 for man test. – andrew lorien Mar 08 '17 at 00:03
  • 2
    Note `man test` (always?) gives the man page for the external-program version, which (for GNU-coreutils version at least) explicitly warns that some (IME most) shells have a builtin version that may be different. – dave_thompson_085 Aug 07 '17 at 09:16