Devop's Shell Programming Cheat Sheet

Stuck with a command? Try explainshell.com

The following posts deal with single Shell commands:

First Things, First! The Shebang: #!

Shebang - the character sequence consisting of the characters number sign and exclamation mark (#!) at the beginning of a script. It is also called sha-bang, hashbang, pound-bang, or hash-pling.

Why is #!/usr/bin/env bash superior to #!/bin/bash?

Neither bash nor env need to be in the given location. So both seem to have the same flaw. It’s up to you!

Using Conditional Expressions within Shell Scripts

This section shows some nice use-cases for conditional Expressions. To dive deeper into this topic please consult the official documentation of Bash Conditional Expressions.

Create a directory if not present

[ -d /opt/planets/bin ] || mkdir -p /opt/planets/bin

Test if environment variable exists - shell script: how to check if an environment variable exists, and get its value?

if [[ -z "${DEPLOY_ENV}" ]]; then
  MY_SCRIPT_VARIABLE="Some default value because DEPLOY_ENV is undefined"
else
  MY_SCRIPT_VARIABLE="${DEPLOY_ENV}"
fi

A simple check if a String variable isn't of size zero

if [ -n "${STOP_AND_REMOVE_CONTAINER}" ]
then
  docker stop planets-server || true
  docker rm planets-server || true
else
  echo "Skipping stop and remove of container."
fi

Browsing through existing code I found this nice snippet: Add trailing slash, if missing:

if [ "${DEST:LEN}" != "/" ]
then
        DEST=$DEST"/"
fi

Grab data from JSON files

This snippet shows how to handle JSON files with ./jq` like a pro:

$ JOB_ID=$(echo $JSON_DOCUMENT | jq -r '.build.jobs[0].jobId')

Note: You can download jq (a lightweight and flexible command-line JSON processor) here

Use a default value in variable assignment

NETWORK_INTERFACE=${NETWORK_INTERFACE_ARG:-"en0"}

Check if a variable is already set

if [ -z "$JAVA_HOME" ]; then
  echo "No JAVA_HOME set. Using default location for Java 8."
  export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
fi

Setting an environment temporarily for one command line

$ LOCAL_BUILD=true echo ${LOCAL_BUILD}

Unzip all files in a directory

$ find . -name '*.zip' -exec unzip {} \;

Create lot's of bogus data with dd:

$ dd if=/dev/urandom bs=1024 count=$((50*1024)) > sample.bin

Check for OSX environment and IP address:

if [ $(uname) == "Darwin" ]
then
  echo "OSX detected."
  NETWORK_INTERFACE=${NETWORK_INTERFACE_ARG:-"en0"}
  DOCKER_HOST_IP=$(ipconfig getifaddr ${NETWORK_INTERFACE})
else
  echo "Defaulting to Linux."
fi

Print a small usage info using a Shell function

usage() {
cat <<-END
Usage: $0 [-h] [-b backup]
  -h help
  -b {backup} to use
END
}if [[ -z "${BACKUP}" ]]; then
  usage
  exit 1
fi

The trickiest part was to get the formatting right: Multi-line string with extra space (preserved indentation).

Substring matching

if [[ ${DOCKER_HOST_IP} == 192.168.* ]]
then
    echo "local development environment detected."
fi

Create multiple directories with one command

Lately I found this nice snippet in a mongoDB online course to create three subdirectories for a cluster setup:

$ mkdir -p /data/db/m040/repl/{1,2,3}

The classical loop

With strings, strings with dash and sub shell commands:

#!/bin/bash

for word in one two "with-dash" "subshell:" $(hostname -f); do
  echo $word
done

May the Shell be with you!

Show Comments