Softpanorama
(slightly skeptical) Open Source Software Educational Society

May the source be with you, but remember the KISS principle ;-)

Google   


Sequences of commands in Unix shell

News

bash

Recommended  Links

    Advanced navigation
if statements Loops in Shell case select Sequences Pipes in Loops 
Arithmetic expressions Comparison operators BASH Debugging Shell history   Etc

Conditional Execution && and ||

All Unix shells allows you to combine exit statuses logically, so that you can test more than one thing at a time:

In both cases it's useful to think about them "short-circuit and" and "short-circuit or," respectively:

They can be used in if statement too:

if statement1 && statement2
then
    ...
fi

Or

if statement1 || statement2
then
    ...
fi

Typical usage is  "cd directory && rm -rf *" (not "cd directory; rm -rf *": If the directory in question does not exist, this command can result in really unintended consequences)

The operator "||" executes the second command only if the first one failed, but it is used is shell much less.  It is more often used is Perl to check if file opened successfully:

open(SYSIN, "$myfile") || die (" cannot open $myfile\n");

You can group commands that are affected by && or || by enclosing them in braces. You have to type a semicolon after the last command of the group. This feature is used relatively rarely, it is needed mainly for putting a sequence of commands in the background (i.e. letting it be executed without blocking the terminal). An example is the UNIX way of reminding yourself when your tea is ready:

{ cd directory && rm -rf * } > ~/Logs/deletion.log

Old News ;-)

List Constructs

The "and list" and "or list" constructs provide a means of processing a number of commands consecutively. These can effectively replace complex nested if/then or even case statements. Note that the exit status of an "and list" or an "or list" is the exit status of the last command executed.

and list
 
   1 command-1 && command-2 && command-3 && ... command-n
Each command executes in turn provided that the previous command has given a return value of true. At the first false return, the command chain terminates (the first command returning false is the last one to execute). 


Example 3-87. Using an "and list" to test for command-line arguments

   1 #!/bin/bash
   2 
   3 # "and list"
   4 
   5 if [ ! -z $1 ] && echo "Argument #1 = $1" && [ ! -z $2 ] && echo "Argument #2 = $2"
   6 then
   7   echo "At least 2 arguments to script."
   8   # All the chained commands return true.
   9 else
  10   echo "Less than 2 arguments to script."
  11   # At least one of the chained commands returns false.
  12 fi  
  13 # Note that "if [ ! -z $1 ]" works, but its supposed equivalent,
  14 # "if [ -n $1 ]" does not. This is a bug, not a feature.
  15 
  16 
  17 # This accomplishes the same thing, coded using "pure" if/then statements.
  18 if [ ! -z $1 ]
  19 then
  20   echo "Argument #1 = $1"
  21 fi
  22 if [ ! -z $2 ]
  23 then
  24   echo "Argument #2 = $2"
  25   echo "At least 2 arguments to script."
  26 else
  27   echo "Less than 2 arguments to script."
  28 fi
  29 # It's longer and less elegant than using an "and list".
  30 
  31 
  32 exit 0

or list
 
   1 command-1 || command-2 || command-3 || ... command-n
Each command executes in turn for as long as the previous command returns false. At the first true return, the command chain terminates (the first command returning true is the last one to execute). This is obviously the inverse of the "and list". 


Example 3-88. Using "or lists" in combination with an "and list"

   1 #!/bin/bash
   2 
   3 # "Delete", not-so-cunning file deletion utility.
   4 # Usage: delete filename
   5 
   6 if [ -z $1 ]
   7 then
   8   file=nothing
   9 else
  10   file=$1
  11 fi  
  12 # Fetch file name (or "nothing") for deletion message.
  13 
  14 
  15 [ ! -f $1 ] && echo "$1 not found. Can't delete a nonexistent file."
  16 # AND LIST, to give error message if file not present.
  17 
  18 [ ! -f $1 ] || ( rm -f $1; echo "$file deleted." )
  19 # OR LIST, to delete file if present.
  20 # ( command1 ; command2 ) is, in effect, an AND LIST variant.
  21 
  22 # Note logic inversion above.
  23 # AND LIST executes on true, OR LIST on false.
  24 
  25 [ ! -z $1 ] ||  echo "Usage: `basename $0` filename"
  26 # OR LIST, to give error message if no command line arg (file name).
  27 
  28 exit 0

Clever combinations of "and" and "or" lists are possible, but the logic may easily become convoluted and require extensive debugging.

 



Copyright © 1996-2007 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. Submit comments This document is an industrial compilation designed and created exclusively for educational use and is placed under the copyright of the Open Content License(OPL). Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

Standard disclaimer: The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

Last modified: April 02, 2008