Bash Tips and Tricks

Go read this cheat-sheet (archive) instead of this file.

A more thorough guide (as opposed to a cheat-sheet) is the BashGuide (archive).

The Bash man page (archive) is also great.

Starting a bash file

#!/bin/bash

set -euo pipefail

From: Bash Strict Mode

If/Else/Elif

The argument to if or elif is a statement, and every statement in sh/bash has a return-value. For the purposes of if, a return value of 0 is true/succes, non-zero is false/failure.

if <condition>; then
  # more statements
fi

Or:

if <condition>; then
  # if-body
elif <condition>; then
  # else-if
else
  # else
fi

Common statements used as if bodies:

Conditions

File exists

if [[ -a "$file" ]]; then
  # do thing
fi

File exists (and is a regular file)

if [[ -f "$file" ]]; then
  # do thing
fi

Directory exists

if [[ -d "$file" ]]; then
  # do thing
fi

Length of string is non-zero

if [[ -n "$var" ]]; then
  # do thing
fi

Length of string is zero

if [[ -z "$var" ]]; then
  # do thing
fi

Command exists

if ! command -v fooBar; then
  echo "fooBar not found!"
  exit 1
fi

Function syntax

function fun_name() {
  # create a function-scoped variable,
  # reference the first and second parameters
  local x="$1 + $2"
  printf "%s" "$x"
}

Temporary files

Single file

temp_file=$(mktemp)
if [[ ! -f "$temp_file" ]]; then
  echo "Unable to allocate temp-file"
  exit 1
fi
function cleanup() {
  rm -f "$temp_file"
}
trap cleanup EXIT

# now do something with your temp-file

Multiple files

# Allocate an entire folder, register to clean it up
temp_dir=$(mktemp -d)
if [[ ! -d "$temp_dir" ]]; then
  echo "Unable to allocate temporary directory"
  exit 1
fi
function cleanup() {
  rm -rf "$temp_dir"
}
trap cleanup EXIT

# Allocate files within the folder
file1=$(mktemp -p "$temp_dir")
file2=$(mktemp -p "$temp_dir")

# Or used fixed file-names - the
# folder should have been created
# with permissions 700.
file3="$temp_dir/foo.txt"

# now do something with the files

This isn’t exactly portable across the different implementations of mktemp - if you need portability the script should define the TMPDIR variable instead of relying on/using the -p argument (some OSes do not have -p, in others -p is ignored if TMPDIR is set). But for GNU this is fine.