01 2018-04-12 BWHPC Course - Adv Bash Scripting
01 2018-04-12 BWHPC Course - Adv Bash Scripting
Funding: www.bwhpc-c5.de
How to read the following slides
Abbreviation/Colour code Full meaning
$ command -opt value $ = prompt of the interactive shell
The full prompt may look like:
user@machine:path $
The command has been entered in the interactive shell session
http://indico.scc.kit.edu/indico/e/bwhpc_course_2018-04-12 or
uc1:/pfs/data1/software_uc1/bwhpc/kit/workshop/2018-04-12
Slides
Exercises
Great at:
managing batch jobs
managing external programs
invoking entire UNIX command stack & many builtins
Powerful scripting language
Portable and version-stable
Bash almost everywhere installed
Be descriptive!
Header
Header
Comment your code
e.g. via headers sections of script and functions. Declarations
Declarations
Decipherable names for variables and functions (of variables+defaults)
(of variables+defaults)
Functions
Functions
Organise and structure!
Break complex scripts into simpler blocks Input
Inputhandling
handling
e.g. use functions
Use exit codes
Use standardized parameter flags for script Main
Mainsection
section
invocation.
Footer
Footer
Sha-Bang = '#!'
→ at head of file = 1. line only! #!/bin/bash
Group commands
In current shell: { cmd1; cmd2; }
In subshell: (cmd1; cmd2)
echo
$ echo hello; echo World
a) trails every output with a „newline“ hello
World
# Comments
at beginning # This line is not executed
at the end echo 'something' # Comment starts here
exception: escaping, quotes, substitution
' Full Quotes = Preserves all special characters within echo '#'
" Partial Quotes = Preserves some of the special characters, but not ${var}
var=42
echo "\${var} = ${var}"; echo '\${var} = ${var}'
$( ) Command subsitution
old version: ` ` (backticks) → do not use anymore
$ echo "today = $(date)"
today = Wed Oct 11 02:03:40 CEST 2017
= filename expansion
→ recognices and expands „wildcards“
but this is not a Regular Expression interpretion (for such use awk/sed)
wildcards:
* = any multiple characters
? = any single character
[] = to list specific character
e.g. list all files starting with a or b $ ls [a,b]*
^ = to negate the wildcard match
e.g. list all files not starting with a $ ls [^a]*
declare – cont.
Arrays: e.g. store file content in array:
a) 1 element per string a=( $(< file) ) = a=( $(cat file) )
b) in-between
$ dt=( ${dt[@]:0:2} ':-)' ${dt[@]:2}} )
$ echo ${dt[@]}
Wed Feb 25 :-) 17:18:22 CET 2015
exe >> log Standard output (stdout) of $ date >> log; cat log
application exe is append to
file log
exe 2> err Standard output (stderr) of $ date 2> err; cat err
application exe is (over)written
to file err
exe 2>> log Standard output (stderr) of $ date 2>> err; cat err
application exe is append to
file log
exe >> log 2>&1 Redirects stderr to stdout $ date >> log 2>&1
exe1 | exe2 Passes stdout of exe1 to # Print stdout & stderr to screen and then append
standard input (stdin) of exe2 both to file
of next command $ date 2>&1 | tee -a log
exe < inp Accept stdin from file inp $ wc -l < file
(ls -yz; date) >> log 2>&1 (ls -yz; date) 2>&1 >> log2
Suppressing stderr
ls -yz >> log 2>/dev/null
→ or use exec
#!/bin/bash
exec > "blah.log" 2> "blah.err" → all stdout and stderr after 'exec'
will be written to blah.log and blah.err resp.
echo "value 1"
command
declare -i i=1
while read -r line ; do
echo "line ${i}: ${line}"
let i+=1
done < 01_input_file
declare -i i=1
while read -r line ; do
echo "line ${i}: ${line}"
let i+=1 Process substition:
done < <(ls -l *) form of redirection; input/output of
process = temp file
20 12/04/2018 Advanced Bash Scripting / R. Barthel
Manipulation of Variables (2)
Example:
${WORKSHOP}/exercises/01/03_var_manipulation.sh
${WORKSHOP}/exercises/01/03_var_manipulation.sh
#!/bin/bash
exe="03_binary.x"
${var: -${def}} If $var not set or is empty, $ var=''; def=new; echo ${var:-${def}}
set value of $def new
readable: [ -r "file" ]
writeable: [ -w "file" ]
executable: [ -x "file" ]
Example #!/bin/bash
i=1
for PP in "${*}" ; do
printf "%3.3s.PP: %s\n" "${i}" "${PP}"
let i+=1
done
Shifting positions:
shift Drops $1 → shifts $2 to $1 → $3 to $2 and so → $# is reduced by 1
→→ Replace
Replace everything
everything betw
betw ...
... and
and ...
... by
by code
code
#!/bin/bash
while ...test total num_positional parameter (PP) greater zero... ; do
case "PP1" in
## script option: -h
...PP is option1...) ...echo something...
;;
...PP is option2...) ...echo PP2...
...do PP shift...
;;
esac
...do PP shift...
done
31 12/04/2018 Advanced Bash Scripting / R. Barthel
Excerise 1: Solution
Processing Input without getopts
Combining: Positional parameter + shift + tests + case + while
${WORKSHOP}/solutions/01/06_proc_input.sh
${WORKSHOP}/solutions/01/06_proc_input.sh
#!/bin/bash
## Purpose: Processing positional parameters
while (( ${#} > 0 )) ; do
case "${1}" in
## script option: -h
-h) echo "${1}: This option is for HELP" ;;
## script option: -i + argument
-i) echo "${1}: This option contains the argument ${2}"
shift ;;
## default
*) echo "${1}: This is non-defined PP" ;;
esac
## Shifting positional parameter one to the left: $1 <-- $2 <-- $3
shift
done
Script execution:
assigned variables only known during runtime
assigned variables not known in „slave“ scripts until „exported“
Example: ${WORKSHOP}/exercises/01/07_master_parse_var.sh
${WORKSHOP}/exercises/01/07_master_parse_var.sh
#!/bin/bash ${WORKSHOP}/exercises/01/08_slave_get_var.sh
${WORKSHOP}/exercises/01/08_slave_get_var.sh
## Purpose: Demonstrate parsing of assigned variables
var1="Non-exported value of var1"
export var2="Exported value of var2"
slave_sh="./08_slave_get_var.sh"
## check if $slave_sh is executable for user
echo "${0}: \$var1 = $var1"
echo "${0}: \$var2 = $var2"
if [ -x "${slave_sh}" ] ; then
"${slave_sh}"
fi
Environmental variables
a) can be read in e.g. my_workDIR=${PWD}
...
## Purpose: Demonstrating effects on environmental variables
awk
→ full-featured text processing language with a syntax reminiscent of C
→ use for complicated arithmetics or text or regular expression processing
Examples:
a) logarithm of variable: a=10; echo ${a} | awk '{print log($1)}'
One-liners: http://www.pement.org/awk/awk1line.txt
sed
→ non-interactive stream editor
→ use for deleting blank or commented lines etc
Example: delete all blank lines of a file: sed '/^$/d' file
One-liners: http://sed.sourceforge.net/sed1line.txt
return : Terminates a function, optionally takes integer = „exit status of the function“
cleanup(){
echo "Cleanup before interrupt and exit"
exit 0
}