Command Lists Logical Operators
October 23rd, 2006
As you may know or read / learned, every command exits with a status. A exit status of 0 is true, while everything else is false. Additionally, the exit status is stored in the $? variable.
This is useful when using command lists, otherwise known as chaining commands together. You can do this with && (and) and || (or). Let me demonstrate:
root@www:~ # true && whoami
root
root@www:~ # false && whoami
true exits with a status of 0 and false exits with a status of 1. true && whoami says “true and whoami” while false && whoami says “false and whoami”. Thus, whoami only executes the first time.
root@www:~ # true || whoami
root@www:~ # false || whoami
root
Here, the || or the logical or is used. whoami only executes when the previous command exits with a non-zero (false) exit status, false || whoami.
Here is a more useful example. You want to rotate a log file. In this situation you want to copy the current log file, truncate the copy in use, and then gzip the copy.
root@www:~ # ls -l syslog*
-rw-r----- 1 root root 63473 Oct 23 11:38 syslog
root@www:~ # cp syslog syslog.1
root@www:~ # echo -n > syslog
root@www:~ # gzip syslog.1
root@www:~ # ls -l syslog*
-rw-r----- 1 root root 63473 Oct 23 11:42 syslog
-rw-r----- 1 root root 6001 Oct 23 11:37 syslog.1.gz
Entering these commands individually works just fine when we are at a BASH prompt. However, because we are smart administrators we want to script this so we do not have to logon everytime to rotate this log file. Since we only want to truncate the log file if it was backed up successfully, we need a better method. We can use the and (&&) operator to achieve this.
root@www:~ # cp syslog syslog.1 && echo -n > syslog && gzip syslog.1
root@www:~ # ls -l syslog*
-rw-r----- 1 root root 63473 Oct 23 11:42 syslog
-rw-r----- 1 root root 6001 Oct 23 11:37 syslog.1.gz
Now I will go over an even more useful example. I have a whole bunch of servers and I want to monitor them so I am informed should one of them crash.
The command below pings bashcurescancer.com once, sending the output to /dev/null. If that ping is unsuccessful it emails me telling me bashcurescancer.com is down. This command would likely be put in crontab and run at some interval.
ping -c 1 -q bashcurescancer.com >/dev/null || echo 'bashcurescancer.com' \
| mail -s 'Server Down' brockn[at]gmail.com
In real life, you will probaly want to throttle it. The following will only email once per hour.
ping -c 1 -q bashcurescancer.com 2>&1 >/dev/null || \
[ ! -f /tmp/pingtest-bashcurescancer.com-`date +%m%d%Y%H` ] && \
touch /tmp/pingtest-bashcurescancer.com-`date +%m%d%Y%H` && \
echo 'bashcurescancer.com' | mail -s 'Server Down' brockn[at]gmail.com


Leave a Reply