Bash Shell Scripting Cheat Sheet

It's like a dos bat file, but with nifty little features, like actual looping constructs and the ability to mess with program output creatively. For a long time, a large fraction of the net's information infrastructure was programmed using shell scripts. The internet worm of 89 used them. Today, skript kiddies use "hack scripts" that are shell scripts that emit C code, compile it, perform the hack, and then clean up after themselves.

Here's a quick cheatsheet. Each line is a valid line in a program.

For more advanced notes Advanced Guide.
For info on doing math, see Bashguru.

 #! /bin/sh
 # THIS IS A COMMENT
 # the first line with /bin/sh is a comment, but it's also a unix script  
 #header that tells the program loader to pass the file to the specified 
 #program, in this case, /bin/sh
 ls ; ls ; # commands on a line are separated by semicolons
 X=10; # sets the environment variable X
 echo $X; # the $X is replaced with 10 before the command is  executed
 X=$HOME; # sets X to the home directory
 ls $HOME; # lists contents of home directory
 FIRSTCOMMANDLINEARGUMENT = $1
 SECONDCOMMANDLINEARGUMENT = $2
 THESHELLSCRIPTSNAMEIS = $0

 echo $VAR 
 echo ${VAR} ; # equivalent, but the latter is useful when you
 echo "FOO${VAR}FOO"; #do this kind of string catenation

 #zsh feature and caveat
 # in zsh, the lowercase variable names evaluate math, while uppercase ones do not
 X=2+3; # "2+3"
 x=2+3; # 5
 x="2+3"; # 5
 # In sh and bash, all the above evaluate to "2+3"
 # to evalutate math in sh, you use $(( expr ))
 x=$((2+3))

 test -e filename; # test is a special command that tests files, in this  case, for existence
 if (test -e $1) then
  echo $1 exists
 elif (test -d $1) then
  echo $1 is a directory
 fi
 # this tests for the existence of a file before proceeding.  The () 
 # evaluates its contents, and uses the return value.  0 means true,  
 # nonzero, false.  (test returns 0 on success)
 # There's a bug in that code.  This is the fixed code
 if (test -e $1 && test ! -d $1) then
  echo $1 exists but is not a directory
 elif (test -d $1) then
  echo $1 is a directory
 fi
 # the && is a shell programming convention that's like a logical AND.
 # It evals the left side, and if the return value is true (0), executes the right side.
 # The counterpart || acts like OR.
 # Sometimes, you see this, which acts like "if the left hand is true, do the right hand"
 test -e $1 && echo "it exists"
 # It's just shorthand.  Likewise, the following means "unless  everything works, do this"
 test -e $1 || echo "the file doesn't exist, aborting" && exit 1

#infinite loop
while true
do
  # commands
done

 for var in a b c d
 do
  rm $var
 done
 # That removes the files a b c and d

 for var in `ls`
 do
  echo "**" $var
 done
 # This lists all the files, prepended by "**"
 # The backticks (`) tell the shell to run the command ls, and then replace itself with the command's output.
 # All commands have three kinds of output - the return value, the output, and the error stream

 # About quotes.  Single quote (') means "don't do variable  substitution inside."  Double quotes (")
 # means don't treat spaces as argument separators, substitute variables, but don't expand filenames.
 # 'this is a string', "this is probably an expression", `this is definitely a command`

 # here's a skeletal mutli-mogrify (the mogrify syntax is wrong, but the overall thing should work)

 if (test ! -e $1) || exit 1
 name=`echo $1 | sed -e 's/[.]jpg$//' `
 for geom in 100 120 150 200 260
 do
   mogrify -format jpeg -outputfile ${name}.${geom}.jpg -geometry ${geom} $1
 done

 # Here's a simplistic "in/out" logger.

 CLOCKSTATE='/home/johnk/bin/clock.on'
 CLOCKLOG='/home/johnk/bin/clock.log'
 if ( test -e $CLOCKSTATE ) then 
	rm $CLOCKSTATE
	echo OUT `date` >> $CLOCKLOG
 else 
	touch $CLOCKSTATE
	echo IN  `date` >> $CLOCKLOG
 fi

 # Here's a way to check if a process is running, and if not, start it.
 @ The sed script looks for XWin, and if it finds it, returns a 'y'

 WINUP=`ps | sed -e 's/.*XWin.*/y/;T end; P;: end; d'`
 echo $WINUP
 if (test y != "${WINUP}") then
        startx &
 else
        echo "X is up"
 fi

 # Here's how to copy a file into multiple directories.
 for i in ../*/ ; do cp theFile $i; done

diff foo bar
RETURNVALUE=$?
if ( test $RETURNVALUE ne 0 ) 

# Bash testing testing syntax puts "then" on a new line
if [[ "$1" == "-w" ]] 
then
    # true stuff
else
    # false stuff
fi

# Bash conditionals are also different, more programmerly.
if [[ "$1" != "-w" ]] ; then
  if [[ "$2" < "M" ]] ; then
    if [[ "$3" > "M" ]] ; then
      # stuff
    fi
  fi
fi
# -lt -gt -eq -ne -ge -le are integer comparison operators.