Bash Scripting Class

From Center for Cognitive Neuroscience
Jump to navigation Jump to search

Class One

Key Terms

  • Shell - a command interpreter. Specifically, a program which takes user input and translates it into instructions the computer can understand
  • Session - a particular instance of a shell. Practically, this is a single Terminal or Xterm window.
  • Variable - A string used to represent some other information. This is very similiar to the connotation of the term as used in mathematics.
  • Scope - A variable's visibility to other parts of a program, script, or shell. I understand that "visibility" is a loaded term, essentially scope determines whether a variable exists within a given context.
  • Environment - variables, paths, etc particular to a shell session.
  • Environment Variable - An environment variable is a particular variable in a shell which holds a value significant to your working environment. Examples include, $PATH, $SHELL, $FSLDIR, etc.
  • Piping - Sending the output of one program as the input to another. Within shell scripting, this is denoted by the | symbol.
  • Special Character - A character which holds a special meaning in the shell environment. Common examples include |, \, /, $, ;

Key points about variables and their use in shells

A variable only retains its value within the scope it is set. Within BASH, a variable is set with the = operator

$ myFirstVar="somevalue"

The contents of a variable is accessed by prepending a $ to the variable name

$ echo $myFirstVar

The following example will demonstrate both variable assignment and scope.

copy/paste the following into a text file named myTemp.sh:

#!/bin/bash

if [ -e ~/.bashrc ];then
  temp="wut"
  echo $temp
fi

echo $temp

Now in your shell type:

$ temp="no wai"
$ echo $temp
$ sh myTemp.sh
$ echo $temp

Your output should look something like

james$ temp='no wai'
james$ echo $temp 
no wai
james$ sh myTemp.sh 
wut
wut
james$ echo $temp
no wai

Now your probably not named james, but the key point is that although the myTemp.sh script acts on a variable called $temp, it only takes on the value of 'wut' for the duration of the script, it then goes back to our original value of 'no wai'. In scripting parlance, we would say "the variable $temp only retained the 'wut' value while in the scope of the temp.sh script".

Piping & redirects

Piping

One of the very powerful features of a unix system is the ability to chain commands together. In this way, a series of very simple programs or operations can build upon each others results to accomplish complex tasks.

Piping is denoted by the | character. A simple example of piping is sorting the output of the ls command like so

$ ls -l | sort

There is no limit to the number of times you can pipe output. For example, this will only display the results of ls which have the word "ninja" in it...in alphabetical order.

$ ls -l | grep "ninja" | sort

And this only prints the 3 and 4th columns of the output of ls which has the word "ninja" in it and it's still in alphabetical order (Oh My!)

$ ls -l | grep "ninja" | awk '{print $3 "   " $4 }' | sort

On each subsequent iteration of the |, it treats the output from the previous executions as its input.

A second useful technique is to send your output to somewhere else, normally a file. This is done using two special symbols

> & >>

The basic syntax is:

$ [some commands and stuff] > [where I want the output to go]

So to save the ouput of ls to a text file named "textfile.txt" you would

$ ls -l > textfile.txt

What's the difference between > and >> then?

> tells the program to save the output to the target and to overwrite any contents the target might contain. >> tells the program to save the output to the target and to add the output to the end of the target preserving previous contents

To make this clear, say you have a text file named nobelPrizeWinningStudy.txt (why on earth you'd save your nobel prize winning report in a text file is beyond me, but hey why not?). If you do this:

$ ls -l > nobelPrizeWinningStudy.txt

nobelPrizeWinningStudy.txt will more appropriately be named "list of files from some random place". Because none of the original nobel prize winning data is left.


Scripting Constructs

Normally you don't just want to list directories and save contents to files, rather you want to take some data and do something useful with it. To do so, it's fairly common to want to perform certain tests, such as "if bank account empty, deposit checks. if bank account not empty.....WIDESCREEN TV"

The basic form of a scripting

This, and virtually all logic constructs consist of one or more of these basic parts:

  • start
  • sufficient condition
  • code (do stuff)
  • close

The 'if' conditional

The if conditional within shell scripting works nicely for taking actions contingent on a particular condition. The basic construct of the if conditional is

if [ test condition ]; then
 do some stuff
fi

In the above example, the corresponding components are

  • start -> if
  • sufficient condition -> [ some test condition ]
  • code -> do stuff
  • close -> fi

We can test multiple conditions or include a default action by including the elif and else condtions like so

 if [ test condition ]; then
   do some stuff
 elif [ test codition2 ];then
   do something different
 else 
   perform default action 
 fi

The for loop

Another very common task is to take perform an action multiple times on multiple inputs. An example would be running several design.fsf files in succession. The for loop provides a perfect mechanism for doing just this.

The basic for loop takes the form

 for i in <sequence of variables>;do
   perform an action on $i
 done

The corresponding components are

  • start -> for
  • sufficient condition -> i is assigned subsequent values of <sequence of variables>
  • code -> perform an action on $i
  • close -> done

A specific implementation might look like

 for i in design1.fsf design2.fsf design3.fsf;do
   echo "Do something with $i"
 done

This would produce an output of

 $ Do something with design1.fsf
 $ Do something with design2.fsf
 $ Do something with design3.fsf

You may have noticed that we declare the variable as i within the for loop, though this could be just about any ascii character or sequence of characters (e.g. myVar). We then act on the value of that variable by placing a dollar sign ($) in front.