Pass the -z option to the if command or conditional expression. If the length of STRING is zero, $var is empty. The syntax is:
[ -z "$var" ] || echo "Empty"
[[ -z "$var" ]] || echo "Empty"
# Check if $var is set using ! i.e. check if expr is false ##
[ ! -z "$var" ] && echo "Empty"
[[ ! -z "$var" ]] && echo "Empty"
Sh/Bash one liner examples
Type the following command
## set _JAIL _JAIL="/path/to/apache" ## find out if it is empty or not ## [ -z "$_JAIL" ] && echo "No" || echo "Yes"
Another example:
_JAIL="" [ -z "$_JAIL" ] && echo "No" || echo "Yes"
Another example:
## unset (remove) $_JAIL ## unset _JAIL [ -z "$_JAIL" ] && echo "No" || echo "Yes"
if command syntax
#!/bin/sh _JAIL="$1" if [ -z "$_JAIL" ] then echo "Please set \$_JAIL" else echo "Setting up jail at $_JAIL" //call setjail() // setjail fi
A note about double bracket syntax
If portability is not your concern try:
## set _JAIL _JAIL="/path/to/apache" ## find out if it is empty or not ## [[ -z "$_JAIL" ]] && echo "No" || echo "Yes"
OR
#!/bin/bash # Warning: Portability issue. _JAIL="$1" ## note double bracket syntax: if [[ -z "$_JAIL" ]] then echo "Please set \$_JAIL" else echo "Setting up jail at $_JAIL" //call setjail() // setjail fi
See also
- Bash Shell: Find Out If a Variable Is Set or Not
- man bash
- man test
- help [
- help [[
You should follow me on twitter here or grab rss feed to keep track of new changes.
Featured Articles:
- 30 Handy Bash Shell Aliases For Linux / Unix / Mac OS X
- Top 30 Nmap Command Examples For Sys/Network Admins
- 25 PHP Security Best Practices For Sys Admins
- 20 Linux System Monitoring Tools Every SysAdmin Should Know
- 20 Linux Server Hardening Security Tips
- Linux: 20 Iptables Examples For New SysAdmins
- Top 20 OpenSSH Server Best Security Practices
- Top 20 Nginx WebServer Best Security Practices
- 20 Examples: Make Sure Unix / Linux Configuration Files Are Free From Syntax Errors
- 15 Greatest Open Source Terminal Applications Of 2012

- My 10 UNIX Command Line Mistakes
- Top 10 Open Source Web-Based Project Management Software
- Top 5 Email Client For Linux, Mac OS X, and Windows Users
- The Novice Guide To Buying A Linux Laptop













{ 14 comments… read them below or add one }
There are a number of advantages of using double brackets for conditionals. One of my favorites is that you do NOT need to use quotes around a variable. It doesn’t matter if it’s empty, has spaces/tabs/newlines in it. You don’t need the quotes.
[ -n "$var" ] || echo EMPTY
Hi,
AFAIK ,the ‘double square brackets’ is bashism and would not work in ‘sh’
The above could be working if ‘sh’ is symlinked to ‘bash’ ?!?
Double brackets were introduced by David Korn in ksh in the early 80s. Bash was introduced in the late 80′s as an open source shell and incorporated nearly all the features of ksh. I don’t think there are any nix’s that don’t have bash or ksh. I last did serious work on Unix around 2001 till I was forced by circumstances to switch to Linux. I’ve used double brackets since the early 90′s and never had a problem. On many of the Linux system’s I’ve worked on, sh was a symlink to bash. When bash is started as “sh”, it behaves differently (sort of brain dead), but I think it still supports the double bracket. It’s hard to know, since by convention, shell scripts have the “shebang” as the first line (#!/bin/bash).
By ‘bashism’ I meant “it is not ‘sh’ syntax”. It would mostly work on “advanced” ‘sh’ compliant shells.
As you can see, in the second example, the interpreter is marked as “bin/sh” and the file contains “double square brackets” syntax, which could fail on so many different oses.
Many non-Linux nixes have only sh (which may or may not be some variant of ksh on solaris, others, I dunno). My recent installation of PCBSD has only csh installed by default. (yuck!)
Many-a-times, AIX installations do not have bash/ksh/whatever by default. Only sh is installed.
All I was saying was … the sentence should clearly state why the “double-square-bracket” syntax could fail, rather than just mentioning “portability”.
*** I know how to install bash on all the platforms, discussing that is not necessary.
The example in question has been updated.
[[ $N ]] || echo “Empty”
When bash is started as sh, the only difference is in which startup files it reads. Its features are unchanged.
The shebang is unnecessary unless the script uses syntax that the default shell doesn’t understand. And if you use a non-standard shell, you can’t be sure where it is. I use systems where bash is either /bin/bash, /usr/bin/bash, /usr/local/bin/bash or /usr/xpg4/bin/bash. You may be safe with “#!/usr/bin/env bash” but I have used systems where env is in /bin, not /usr/bin.
I don’t use double brackets. The only thing they give that you can’t do without them is comparing a string against a regular expression (and I have very little need for that).
The shebang saves a bit of time. (It tells the shell what to use to run the program. Otherwise, it has to figure it out. It forks itself as the last resort.) I’ve been using Linux almost exclusively for the last ten or so years, but have occasionally used other ‘nix’s (most recently AIX). I’ve not had a problem with the location of bash.
There are several reasons Korn added double bracket. If you remember your history, the original condition checker was “test”, located in /bin. Then came “[...]“. Actually ‘[' was a hard link to /bin/test. After a while, these were converted to built-ins, but due to backward compatiblity requirements, no advantage could be taken of this (other than improved performance).
Korn introduced double brackets to get around the backward-compatibility requirement. The problem with single bracket is that all the command line parsing is completed before the condition is tested. That's why quotes are often necessary.
If you use "type [" you will see "[ is a shell builtin". Builtins act like programs. If you use "type [[", you will see "[[ is a shell keyword". The difference is that the shell sees the keyword and knows what's going on. It knows that $var is a variable. And that's why variables need not be quoted. Ever. Further, double bracket knows what "||" and "&&" are. So, you don't need to use "-o" and "-a". Example:
[[ -f $File && -r $File ]] || echo “‘Not a readable file: ‘$File’”
Finally, as noted before, you can compare strings (or variable) to shell patterns (not regular expressions). This can be truly useful. For example:
[[ $S3Msg = ERROR:* ]] && S3Stat=1
A friendly vendor gave me “The Korn Shell” by David Korn in the early nineties. I’ve been forever grateful. I’ve adopted all the new features, and (due to other things), got as much as a 200 times performance improvement over the old Bourne Shell. When I was forced to move to bash (because pdksh was so buggy), I soon figured out that the minor incompatibilities in no way reduced the functionality of bash. I’ve learned to love it.
You can compare strings or variables against a pattern without using double brackets;use a case statement:
You don’t need double brackets to use && or || with test:
Having to quote variables is not a problem; not doing it leads to bad habits.
Using a case statement is a lot of trouble to avoid writing a compound conditional. And don’t get me started on case statements without the leading paren in the condition statements!
The second form, where you put “&&” and “||” between the condition checks is actually worse than just using -a and -o. And to what purpose? Double bracket solves the problem!
The comment on “bad habits” … what can I say? I’ve heard people say the same thing about always using braces in their variables: ${x}. If you know what you are doing, you know when braces are necessary. You know when quotes are necessary (or desireable). Certainly, you get different results between ‘echo $x’ and ‘echo “$x”‘. If you know what you are doing, you know which is correct for the situation.
A case statement is no trouble and is much more flexible than [[ ... ]]. And it’s portable; [[ ... ]] is not.
Why is && worse than -a?
The use of -a and -o is deprecated in the POSIX standard.
That’s the point. Not only is a case statement no trouble (as you say), double bracket is even less than no trouble. We regard to portability, I’ve been doing shell programming since 85. There were a LOT of issues with Bourne Shell on all the different ‘nix’s that I worked with. (They were “compatible”. NOT!) They claimed to obey the same rules, but the rules were incomplete, and there were differences in limitations. For example, on Ultrix, you were limited to 20 levels of recursion — and that was a BEAR to debug! The solution(s) were to (a) try to figure out a subset of stuff that worked; and (b) try to find a shell on each flavor of Unix (MIPS, IBM, DEC, SCO, DG, NCR, ETC) that would always work (and to write some clever code that could determine what machine you were on and re-launch the script with that shell). I found ksh this way.
Then this DG guy told me that ksh was now on all Unixes. And he gave me “The Korn Shell”. That was around 1993. I looked on all the machines in house (list above) and found that it was true. I read the book and wrote pages of notes on what could be done and how that would help. For example, I found that using ((Idx = 0; Idx < $X; Idx++)) was roughly 200 times faster than using "Idx=`expr $Idx + 1`" in a loop and then testing $Idx -ge $X.
So, just how "non-portable" is double bracket? It's portable. With an exception. At some point I ran into a Linux that uses "dash" to run the startup scripts. Dash is a minimal shell, but it's very fast. If you write anything that will execute on startup, you should take the precaution of putting the shebang in the first line. (Should always be there anyway … ya never know when someone will launch your script with zsh or some other odd duck. It's faster, too.)
I found that the pattern matching ability of double-bracket was roughly 200 times faster than echoing a variable through grep and testing the result.
I found that "$(< file)" was roughly 200 times faster than `cat file`. And I found a great deal of advantage in being able to nest $(…). (You can nest backticks, but you have to backslash 'em.) This, by the way, is why Korn introduced leading (left) parens in the condition tests of case statements. It let you embed case statements in $(…) command line substitutions. That is, it lets you keep your parens balanced.
You asked why "&&" is worse than -a. It's all context. With double brackets, you use "&&" and "||" to express a compound condition. With single brackets, you use "-a" and "-o" for the same purpose. It can be a bit trickier, because the shell interprets the line before the condition check takes place. Regardless, these are equivalents.
Where I said "&&" is worse than -a, I was pointing out that the example was avoiding compound conditionals by making the simple conditionals and using "&&"/"||" between them.
I don't read posix standard. That's because I'm the victim here. I use what the gods give me. I'm gonna guess, however, that -a and -o are deprecated because double bracket is the standard.
“Portable” means complying with the POSIX standard.
The Bourne shell could not be counted on to be the same on all systems; the POSIX shell can.
[[ ... ]] cannot be counted on; [ ... ] can, and is (with help from case) adequate for almost all needs.
And, no, -a and -o are not deprecated because [[ ... ]] is standard; it’s NOT. They are deprecated because they can lead to confusion and are not reliable in all cases. Where thare are more than 4 elements in a test expression, the result is undefined and cannot be depended on. Multiple tests separated by && or || always work.
The double brackets are insignificantly faster than single brackets, nowhere near 200 times.
Dash/ash is a POSIX shell; if you write POSIX-compliant scripts, they will run on dash — as well as ksh and bash.