Bash Syntax

Builtins

Variables

Variable assignments must not use spaces. $ can be used to get values from variables.

varname=variablevalue
var2name="value with spaces"

echo $varname
echo "some text $varname some more"
echo 'singlequotes $dont interpolate values'
echo "can wrap ${varname} in curly backets"

Backslashes can be used to escape characters.

To get the value of programs into text strings, wrap the commands in brackets.

echo "the time is now $(timenow)"

Variables are scoped to their script by default. They can be exported so they can accessed externally or by child processes.

export PS1

Variable Expansion

Curly brackets around a variable can be used in more complex ways:

echo "can wrap ${varname} in curly backets"
echo "can use hash to get ${#varname} in length of variable"
echo "can will use word instead of parameter if parameter is undefined or null ${parameter:-word}"

There are more of these, see here.

if statements

From here.

if
    command-list1
then
    conditional-commands1
elif
    command-list2
then
    conditional-commands2 
else
    conditional-commands3
fi

The then clause is executed if the exit code of command-list1 is 0. The command-list1 can be a sequence of one or more pipelines separated by one of the operators ;, &, &&, || or newline. There are some common idioms that are special cases of this:

[ ]

if [ condition ]

This is equivalent to POSIX test, which can do a number of comparisons and evaluations.

[[ ]]

if [[ condition ]]

This is an upgraded variation of test, which can do more advanced comparisons like wildcard string comparisons. Not POSIX.

(( ))

if ((condition))

This performs arithmetic, with the result being the exit code of the pipeline. Not POSIX.

( )

if (command)

This runs the command as a subshell, which can limit side effects.

Shell Arithmetic

Operations

Globbing

A method of wildcard matching.

case statements

case <expression> in
    <pattern>[ | <pattern>...]) <statements>;;
esac

Pattern should be a glob pattern. * is used as the else statement as it will match everything.

Loops

break and continue do what you'd expect.

for loop

for <name> in <list> do
    <commands>
done

list is just a list of white-space seperated strings. Good for use with globbing and file names, or reading through textfiles, especially when used in combination with $IFS.

for loops can also use this format (Bash only)

for ((init; check; step)); do
    body
done

while loop

while [ condition ]; do
   <command3>
done

shift

Functions

function name {
    <commands>
    return [<exit status>]
}

Use $1, $2 for parameters. $0 is the function name.

All variables are global unless local keyword is when declaring variable.

Process Substitution

Process substitution allows you to replace an input and output file arguments, for example.

diff <(hexdump file1.bin) <(hexdump file2.bin)
cat file.txt | tee >(wc -l)

It's similar to using temporary files but nothing gets written to disk.

I learnt of process substitution from this thread (unrolled).