Skip to content

Instantly share code, notes, and snippets.

@khalidx
Created October 2, 2023 22:12
Show Gist options
  • Save khalidx/cbbcdde96b09a4852e1042a98af7ed44 to your computer and use it in GitHub Desktop.
Save khalidx/cbbcdde96b09a4852e1042a98af7ed44 to your computer and use it in GitHub Desktop.
Reusable bash functions.

Include the code below in any bash script!

This is a good way to start a bash script:

#!/usr/bin/env bash
set -eou pipefail

These are some useful generic reusable bash functions.

cdScriptDirectory() {
  cd "$(dirname "$0")"
}

cdBack() {
  cd - > /dev/null
}

notEmpty() {
  local text="$1"
  if [ -z "$text" ]; then
    echo 'Invalid argument.'
    exit 1
  else
    echo "$text"
  fi
}

Here are some more functions, specifically for performing Docker operations:

dockerMakeFilter() {
  local docker_label_key=$(notEmpty "$1")
  local docker_label_value=$(notEmpty "$2")
  echo "label=$docker_label_key=$docker_label_value"
}

dockerFilterContainers() {
  local docker_label_filter=$(notEmpty "$1")
  echo $(docker container ls --all --no-trunc --format '{{.ID}}' --filter "$docker_label_filter")
}

dockerFilterNetworks() {
  local docker_label_filter=$(notEmpty "$1")
  echo $(docker network ls --no-trunc --format '{{.ID}}' --filter "$docker_label_filter")
}

dockerFilterVolumes() {
  local docker_label_filter=$(notEmpty "$1")
  echo $(docker volume ls --format '{{.Name}}' --filter "$docker_label_filter")
}

dockerListAll() {
  local docker_label_filter=$(notEmpty "$1")
  local containers=$(dockerFilterContainers "$docker_label_filter")
  local networks=$(dockerFilterNetworks "$docker_label_filter")
  local volumes=$(dockerFilterVolumes "$docker_label_filter")
  echo "FILTER $docker_label_filter"
  for item in $containers; do echo "CONTAINER $item"; done
  for item in $networks; do echo "NETWORK $item"; done
  for item in $volumes; do echo "VOLUME $item"; done
}

dockerStartAll() {
  local docker_compose_directory=$(notEmpty "$1")
  cd "$docker_compose_directory"
  docker compose up --wait --wait-timeout 60 || echo "Failed while starting: $docker_compose_directory"
  cdBack
}

dockerStopAll() {
  local docker_label_filter=$(notEmpty "$1")
  local containers=$(dockerFilterContainers "$docker_label_filter")
  docker container stop $containers
}

dockerPurgeAll() {  
  local docker_label_filter=$(notEmpty "$1")
  local containers=$(dockerFilterContainers "$docker_label_filter")
  local networks=$(dockerFilterNetworks "$docker_label_filter")
  local volumes=$(dockerFilterVolumes "$docker_label_filter")
  docker container stop $containers
  docker container rm $containers
  docker network rm $networks
  docker volume rm $volumes
}

if [ $# -eq 0 ]; then echo 'No arguments supplied.'; exit 1; fi

command="$1"

if [ "$command" == 'start' ]; then
  if [ $# -ne 2 ]; then echo 'Exactly two arguments must be supplied.'; exit 1; fi
  docker_compose_directory="$2"
  dockerStartAll "$docker_compose_directory"
  echo 'Done!'
else
  if [ $# -ne 3 ]; then echo 'Exactly three arguments must be supplied.'; exit 1; fi
  docker_label_key="$2"
  docker_label_value="$3"
  docker_label_filter=$(makeFilter "$docker_label_key" "$docker_label_value")
  if [ "$command" == 'ls' ]; then
    dockerListAll "$docker_label_filter"
  elif [ "$command" == 'stop' ]; then
    dockerStopAll "$docker_label_filter"
    echo 'Done!'
  elif [ "$command" == 'purge' ]; then
    dockerPurgeAll "$docker_label_filter"
    echo 'Done!'
  else
    echo 'Invalid arguments.'
    exit 1
  fi
fi

Here's another way of doing something similar to the Docker functions above, but shorter. The Docker functions above were inspired by this:

if [ $# -eq 0 ]; then echo 'No arguments supplied.'; exit 1; fi
if [ $# -ne 2 ]; then echo 'Exactly two arguments must be supplied.'; exit 1; fi

docker_label_key="$1"
docker_label_value="$2"
docker_label_filter="label=$docker_label_key=$docker_label_value"

containers=$(docker container ls --all --no-trunc --format "{{.ID}}" --filter $docker_label_filter)
networks=$(docker network ls --no-trunc --format "{{.ID}}" --filter $docker_label_filter)
volumes=$(docker volume ls --format "{{.Name}}" --filter $docker_label_filter)

docker container stop $containers
docker container rm $containers
docker network rm $networks
docker volume rm $volumes
@khalidx
Copy link
Author

khalidx commented Oct 2, 2023

  • Bash does strange things like sets values THEN exits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment