Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagebash
my_script.sh helloWorld      # invoke the "helloWorld" functionality of my_script.sh
my_script.sh goodbyeWorld    # invoke the "goodbyeWorld" functionality of my_script.sh

There are many examples of command-processing scripts in bioinformatics: bwa, bowtie2, samtools, to name but a very few.

The step_01.sh Script

Here's a basic command-processing script with one sub-command. This script can be found in your home directory in ~/workshop/step_01.sh. Make sure it is executable (chmod +x ~/workshop/step_01.sh).

Code Block
languagebash
titlestep_01.sh
#!/bin/bash

# Script version global variable. Edit this whenever changes are made.
__ADVANCED_BASH_VERSION__="step_01"

# function that says "Hello World!" and displays user-specified text.
function helloWorld() {
  local txt1=$1
  local txt2=$2
  shift; shift
  local rest=$@

  echo "Hello World!"
  echo "  text 1: '$txt1'"
  echo "  text 2: '$txt2'"
  echo "  rest:   '$rest'"
}

# =======================================================================
#  Main script command-line processing
# =======================================================================

function usage() {
  echo "advanced_bash.sh, version $__ADVANCED_BASH_VERSION__"
  echo ""
  echo "Usage: advanced_bash.sh <command> [arg1 arg2...]"
  echo ""
  echo "Commands:"
  echo "helloWorld [text to display]"
  echo ""
}

CMD=$1  # initially $1 will be the command
shift   # after "shift", $1 will be the 2nd command-line argument; $2 the 3rd, etc.
        # and $@ will be arguments 2, 3, etc.
case "$CMD" in
  helloWorld) helloWorld "$@"
    ;;
  *) usage
    ;;
esac

...

The first line (#!/bin/bash) is called the shebang #! characters followed by the full path to the program which should execute the script, if it is invoked without an execution context .

...

(and if it has execute file permissions of course (smile)).

Code Block
languagebash
# Call a script directly. 
# As long as it marked as executable (chmod +x), the shell 
# peeks at the shebang line and passes the script to that program.
~/workshop/step_01.sh

# Call a script specifying the executing program. The shebang line will be ignored.
bash ~/workshop/step_01.sh

...

  • when referencing a positional argument variable with more than one digit (e.g. ${10})
  • to separate the variable evaluation from text immediately following (e.g. "${prefix}_file.txt")
    • since underscore characters ("_") are allowed in variable names, the braces are needed so that the shell does not think the variable name is prefix_file.

Functions

A bash function looks like this, with or without the function keywordExample:

Code Block
languagebash

...

function my_function() {
  # code goes here
}
myvar="some text"
echo $myvar
echo ${myvar}
echo $myvar_more_text   # no output because the variable myvar_more_text is not defined
echo ${myvar}_more_text

Functions

A bash function looks like this, with or without the function keyword.


Code Block
languagebash
function my_function() {
  # code goes here
}

Function and script arguments

...



Code Block
languagebash
my_function() {
  # code goes here
}


Function and script arguments

Just like the script as a whole, arguments to a bash function are positional, and are referenced using:

  • positional variables $1 $2 ... $9  ${10}  ${11}...
  • or $@ to refer to all of the arguments
  • and $0 to refer to the script name itself

...

  • to refer to the script name itself

Note that while a function can have many arguments, the function definition never contains anything in its ( ) "formal argument list".

Example:

Code Block
languagebash
function myfn() { echo "arg 1: $1"; echo "arg 2: $2"; echo "all args: $@"; }
myfn foo bar baz

In our script, the shift keyword "pops" the first element off the argument list.Note that while a function can have many arguments, the function definition never contains anything in its "formal argument list".

Since there is no formal argument list, it is good practice to copy function arguments into local variables with names suggesting their role. (e.g. local txt1=$1). The local keyword specifies that the variable scope is only within the function body – it is not visible to the caller or to called functions.

...

Code Block
languagebash
CMD=$1  # initially $1 will be the command
shift   # after "shift", $1 will be the 2nd command-line argument; $2 the 3rd, etc.
        # and $@ will be arguments 2, 3, etc.
case "$CMD" in
  helloWorld) helloWorld "$@"
    ;;
  *) usage
    ;;
esac

...