...
While bash scripts can be written to perform a single function, another style is to have a script perform multiple functions, where the functionality to be performed is specified by the first command argument to the script. This is the script style we 'll will explore here.
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 |
...
The first line (#!/bin/bash
) is called the shebang – which consists of #! 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. # Here the shell (bash) passes the script to itself (/bin/bash) ~/workshop/step_01.sh # Call a script specifying the executing program. The shebang line will be ignored. # In this case, the script does not even have to be marked as executable! bash ~/workshop/step_01.sh |
...
The variable's value is referenced by prefixing the variable name with the dollar sign $, or by enclosing it in braces prefixed by the dollar sign ${}. Usually these two forms are equivalent, except:
- 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.
...
When defining or evaluating environment variables there's also a difference between enclosing the value in double quotes ( "$foo$foo" ) or single quotes ( '$foo$foo' ) – see Intro Unix: Quoting in the shell.
Example:
Code Block | ||
---|---|---|
| ||
myvar="some text" echo "$myvar" echo '$myvar' |
...
- individual positional variables $1 $2 ... $9 ${10} ${11}...
- or $@ to refer to all of the arguments
- and $0 to refer to the script file name itself
Note that while a function can have many arguments, the function definition never contains anything in its ( ) "formal argument list". Weird, eh?
...
In our script, the shift keyword "pops" the first element off the argument list.
...
Importantly, if an argument to be passed itself contains spaces, the argument must be enclosed in single or double quotes (or, more ugly, the spaces can be backspace-quotedescaped, e.g. "\ ")
Code Block | ||
---|---|---|
| ||
# Call a custom script passing 2 arguments my_script.sh arg1 "arg2 has embedded spaces" # Call a function passing 2 arguments my_function arg1 'arg2 has embedded spaces' |
...
Code Block | ||
---|---|---|
| ||
function myfn() { echo "arg 1: $1"; echo "arg 2: $2"; echo "all args: $@"; } myfn foo bar baz wonk myfn foo "bar baz" wonk myfn "foo bar" baz wonk |
As described in Intro Unix: Quoting in the shell, this is the main function of both single and double quotes – to group text containing whitespace into one item.
...
Script arguments will initially be:
- $1 - helloWorld
- $2 - My
- $3 - name
- $4 - is
- $5 - Anna
- $@ - helloWorld My name is Anna
Command line processing captures the 1st script argument then pops it off with shift.
...
After shift is called, script arguments are:
- $1 - My My
- $2 - name name
- $3 - is is
- $4 - Anna Anna
- $@ - My name is Anna
The CMD variable matches the helloWorld) clause of the case/esac statement, so arguments are passed to the helloWorld function in the "$@" built-in variable.
...
Initially helloWorld arguments are:
- $1 - My → stored in local variable txt1
- $2 - name → stored in local variable txt2
- $3 - is
- $4 - Anna
- $@ - My name is Anna
After shift; shift is called, helloWorld arguments are:
- My → previously now stored in local variable txt1
- name → previously now stored in local variable txt2
- $1 - is
- $2 - Anna
- $@ - is Anna → stored in local variable rest
...
Expand | |||||
---|---|---|---|---|---|
| |||||
|
...
We;ve already touched on difference kinds of Quoting in the shell. But there is an additional subtlety when handling script arguments.
...
Code Block | ||
---|---|---|
| ||
# Wihout quotes, all argument grouping by the script caller is lost!
helloWorld $@
# With quotes, argument quoting by the script caller is preserved
helloWorld "$@" |
...
Expand | |||||
---|---|---|---|---|---|
| |||||
Here single quotes or backslash must be used so that the shell does not try to evaluate "$foo$foo" and "\" before passing the arguments into the script.
|
...