Bash Scripting Notes
Shell Parameter Expansion
Shell Parameter Expansion (Bash Reference Manual)
Null and Unset
${parameter:-word}
: if (parameter is unset or null) then word else parameter${parameter:=word}
: if (parameter is unset or null) { parameter=word; word } else${parameter:?word}
: if (parameter is unset or null) { print word to stderr; exit 1 } else${parameter:+word}
: if (parameter is unset or null) { null } else
Remove Matching Prefix/Suffix
${parameter#word}
: remove smallest matching prefix pattern${parameter##word}
: remove largest matching prefix pattern${parameter%word}
: remove smallest matching suffix pattern${parameter%%word}
: remove largest matching suffix pattern
E.g. file='a/b/file.tar.gz'
${file#*/}
:b/file.tar.gz
${file##*/}
:file.tar.gz
${file%/*}
:a/b
${file%%/*}
:a
${file%.*}
:a/b/file.tar
${file%%.*}
:a/b/file
${file#*.}
:tar.gz
${file##*.}
:gz
Control Flow
Compound Commands (Bash Reference Manual)
Semicolons are used to separate commands on the same line. They can be replaced with newlines.
if condition; then ...; [elif condition; then ...;] [else ...;] fi
for var in ...; do ...; done
while condition; do ...; done
Conditional Expressions
Conditional Constructs (Bash Reference Manual)Conditional Expressions (Bash Reference Manual)
What's the difference between [
and [[
in Bash? (Stack Overflow)
[[
is bash's improvement to the [
command. It has several enhancements that make it a better choice if you write scripts that target bash. My favorites are:
It is a syntactical feature of the shell, so it has some special behavior that
[
doesn't have. You no longer have to quote variables like mad because[[
handles empty strings and strings with whitespace more intuitively. For example, with[
you have to writebashif [ -f "$file" ]
to correctly handle empty strings or file names with spaces in them. With
[[
the quotes are unnecessary:bashif [[ -f $file ]]
Because it is a syntactical feature, it lets you use
&&
and||
operators for boolean tests and<
and>
for string comparisons.[
cannot do this because it is a regular command and&&
,||
,<
, and>
are not passed to regular commands as command-line arguments.It has a wonderful
=~
operator for doing regular expression matches. With[
you might writebashif [ "$answer" = y -o "$answer" = yes ]
With
[[
you can write this asbashif [[ $answer =~ ^y(es)?$ ]]
It even lets you access the captured groups which it stores in
BASH_REMATCH
. For instance,${BASH_REMATCH[1]}
would be "es" if you typed a full "yes" above.You get pattern matching aka globbing for free. Maybe you're less strict about how to type yes. Maybe you're okay if the user types y-anything. Got you covered:
bashif [[ $ANSWER = y* ]]
Functions
function_name() { ...; }