Published on

Bash Cheatsheet

Authors
  • avatar
    Name
    Justin D Vrana
    Twitter

This post contains quick reference for common BASH functions and tasks. Enjoy!

Requiring string value for a parameter

By default, adding something like --host will default to "1". We validate that this value is not equal to one using this.

### Validation. Error out if the things required for your script are not present
##############################################################################

[[ "${arg_z:-}" ]] && [[ "${arg_z}" != "1" ]] || help "Setting a host with --host is required"

Arg parsing

#!/bin/bash

POS_ARGS=()

FLAG0=NO
while [[ $# -gt 0 ]]; do
  case $1 in
    -e|--extension)
      KWARG1="$2"
      shift # past argument
      shift # past value
      ;;
    -s|--searchpath)
      KWARG2="$2"
      shift # past argument
      shift # past value
      ;;
    --default)
      FLAG0=YES
      shift # past argument
      ;;
    -*|--*)
      echo "Unknown option $1"
      exit 1
      ;;
    *)
      POSITIONAL_ARGS+=("$1") # save positional arg
      shift # past argument
      ;;
  esac
done

set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters

echo "KWARG2  = ${KWARG1}"
echo "KWARG2  = ${KWARG2}"
echo "FLAG0   = ${FLAG0}"

if [[ -n $1 ]]; then
    echo "Last line of file specified as non-opt/last argument:"
    tail -1 "$1"
fi

Logging to File

# redirect stdout to screen and to log file
# redirect sterr to stdout
if [[ $silent -eq 1 ]]; then
	exec 1>>$log_file 2>&1
else
	exec 1>>>(tee -a "$log_file") 2>&1
fi

KillTree

Recursively kill processes.

killtree() {
	# debug "Killing Processes [BEGIN]"
	local _pid=$1
	local _sig=${2:--TERM}
	# debug "kill -stop ${_pid}"
	[[ ${_pid} != $$ ]] && kill -stop ${_pid} 2>/dev/null || true
	for _child in $(ps -o pid --no-headers --ppid ${_pid}); do
		killtree ${_child} ${_sig}
	done
	[[ ${_pid} != $$ ]] && kill ${_sig} ${_pid} 2>/dev/null || true
	# debug "kill ${_sig} ${_pid}"
}

function cleanup_on_term () {

	for pid in "${pids[@]}"
	do
		echo "killing $pid"
		echo "----------------------------------------------------"
		echo "--- Terminating GRPC Server for '${projectName}' ---"
		echo "----------------------------------------------------"
		killtree $pid
	done
}

trap cleanup_on_term TERM INT USR2

Size of Directories

du . --max-depth=1 --apparent-size -h

alias lll=du . --max-depth=1 --apparent-size -h

Reading a File Line By Line

filename='myfile.txt'

while IFS= read -r line || [[ -n "$line" ]]
do
echo "$line"
done < "$filename"

Getting Default Value in A Function

function example_func {
  local arg=${1:-"default value"}
  echo "$arg"
}

Cleaning up disk space (use caution)

Eval Disk Space

sudo du -cha --max-depth=1 /var/log | grep -E "M|G"

Clean Up Journal

sudo journalctl --vacuum-size=100M
sudo journalctl --vacuum-time=10d

Edit the Journal Config

sudo vim /etc/systemd/journald.conf

CookBook

1. Variables

Set a variable:

variable="Hello World"

Access a variable:

bash

echo $variable

2. Arrays

Define an array:

arr=("element1" "element2" "element3")

Access an array element:

echo ${arr[0]}  # Outputs "element1"

3. Functions

Define a function:

my_function() {   echo "Hello from function" }

Call the function:

my_function

4. Arguments to Functions

my_function() {
  echo "First argument is $1"
  echo "Second argument is $2"
}

my_function "Hello" "World"

5. Default Arguments

If you want to provide a default value for an argument, use this syntax:

my_function() {
  local arg=${1:-"default value"}
  echo $arg
}

6. Conditionals

if [ $1 -gt 100 ]
then
  echo "Greater than 100"
else
  echo "Not greater than 100"
fi

7. Looping Over a File Line-by-Line

while IFS= read -r line || [[ -n "$line" ]]
do
  echo "$line"
done < "filename"

8. Looping Over an Array

for element in "${arr[@]}"
do
  echo "$element"
done

9. Splitting a String into an Array

line="Split this line into words"
arr=($line)

10. Checking if a File Exists

if [ -f "filename" ]
then
  echo "File exists"
else
  echo "File does not exist"
fi

11. Sending Output to a File

echo "Hello, World" > output.txt

12. Appending Output to a File

echo "Hello, again" >> output.txt

13. Pipe output from one command to another

ls -l | grep ".txt"

14. Run a Command in the Background

command &

15. Run a Command with a Timeout

timeout 10 command   # Timeout after 10 seconds

16. Redirect both stdout and stderr to a File

command &> filename

17. String Concatenation

str1="Hello,"
str2=" World!"
str3="$str1$str2"
echo "$str3"  # Outputs "Hello, World!"

18. String Length

str="Hello, World!"
echo ${#str}  # Outputs "13"

19. Command Substitution Use command substitution when you want to use the output of a command as an argument to another command.

date_today=$(date +%Y-%m-%d)
echo "Today's date is $date_today"

20. Arithmetic Operations

a=10
b=20
sum=$((a + b))
echo "The sum is $sum"

21. Case Statements

case "$variable" in
  pattern1)
    command1
    ;;
  pattern2)
    command2
    ;;
  *)
    default_command
    ;;
esac

22. Check Whether a Command Succeeded

command
if [ $? -eq 0 ]
then
  echo "The command succeeded"
else
  echo "The command failed"
fi

23. Substrings

string="Hello, World!"
substring=${string:7:5}  # start at 7th character, length 5
echo "$substring"  # Outputs "World"

24. Path of the Running Script

script_path="$(dirname "${BASH_SOURCE[0]}")"
echo "$script_path"

25. Sleep

sleep 5  # Pauses the script for 5 seconds

26. Check If a Program Is Installed

bash

if command -v "program" > /dev/null 2>&1
then
  echo "Program is installed"
else
  echo "Program is not installed"
fi

27. Infinite Loop

while true
do
  command
done

28. Exit the Script

exit 0

29. Exit the Script with an Error Message

echo "Error message" 1>&2
exit 1

30. Running Commands from a File (Sourcing)

source filename

31. Here Document

command <<EOF
input1
input2
input3
EOF

32. Process Substitution

diff <(command1) <(command2)

33. Using Find to Recursively Search for Files

find . -name '*.txt' -print

34. Using Grep to Search for Text Within Files

grep -r 'pattern' .

35. Use Sed for Stream Editing

echo "Hello, World" | sed 's/World/Earth/'

36. Use Awk for Text Processing

echo -e "field1\tfield2\tfield3" | awk '{print $2}'

37. Use Xargs to Build and Execute Commands from Standard Input

find . -name '*.txt' -print | xargs rm

38. Background Jobs and Job Control

command &  # Start a job in the background
jobs  # Li jobs
fg %1  # Bring job 1 to the foreground

39. Reading and Writing to File Descriptors

exec 3> file  # Open "file" for writing on file descriptor 3
echo "This is a test" >&3  # Write to file descriptor 3
exec 3>&-  # Close file descriptor 3

40. Use Trap to React to Signals

trap 'echo "Signal received"' SIGINT SIGTERM

41. Here Strings

command <<< "Here string"

42. Script Arguments

POSITIONAL_ARGS=()

while [[ $# -gt 0 ]]; do
case $1 in
-c|--command)
COMMAND="$2"
shift # past argument
shift # past value
;;
-b|--branch)
BRANCH="$2"
shift # past argument
shift # past value
;;
-*|--*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done

set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters

COMMAND=${COMMAND:-${POSITIONAL_ARGS[0]}}

echo "BRANCH = ${BRANCH}"
echo "COMMAND = ${COMMAND}"
# the following are equivalent, all "doA".
myscript doA
myscript --command doA
myscript doB --command doA