...
Code Block | ||
---|---|---|
| ||
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 | ||||
---|---|---|---|---|
| ||||
#!/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 ).
Code Block | ||
---|---|---|
| ||
# 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 | ||
---|---|---|
|
...
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.
|
Function and script arguments
...
|
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 |
...