DEV Community

Cover image for The Only Bash Scripting Cheat Sheet That You Will Ever Need
Bobby Iliev
Bobby Iliev

Posted on • Edited on • Originally published at devdojo.com

The Only Bash Scripting Cheat Sheet That You Will Ever Need

Introduction

No matter if you are a DevOps/SysOps engineer, developer, or just a Linux enthusiast, you can use Bash scripts to combine different Linux commands and automate boring and repetitive daily tasks, so that you can focus on more productive and fun things.

Here you can find the completed Bash Scripting cheat sheet 👇

Bash Script Header (Shebang)

Option 1:

#!/bin/bash
Enter fullscreen mode Exit fullscreen mode

Option 2:

#!/usr/bin/env bash
Enter fullscreen mode Exit fullscreen mode

Variables

#!/bin/bash
name="DevDojo"
echo "Hi there $name"
Enter fullscreen mode Exit fullscreen mode

User Input

#!/bin/bash

echo "What is your name?"
read name

echo "Hi there $name"
echo "Welcome to DevDojo!"
Enter fullscreen mode Exit fullscreen mode

Comments

To do that in bash you need to add the # symbol at the beginning of the line. Comments will never be rendered on the screen.

# This is a comment and will not be rendered on the screen
Enter fullscreen mode Exit fullscreen mode

Arguments

#!/bin/bash

echo "Argument one is $1"
echo "Argument two is $2"
echo "Argument three is $3"
Enter fullscreen mode Exit fullscreen mode

Then run the file and pass 3 arguments:

bash ./arguments.sh dog cat bird
Enter fullscreen mode Exit fullscreen mode

Arrays

my_array=("value 1" "value 2" "value 3" "value 4")

# Access a single element, this would output: value 2
echo ${my_array[1]}

# This would return the last element: value 4
echo ${my_array[-1]}

# This would output the total number of elements in the array, in our case it is 4:
echo ${#my_array[@]}
Enter fullscreen mode Exit fullscreen mode

Conditional Expressions

File expressions

## True if file exists.
[[ -a ${file} ]]

## True if file exists and is a block special file.
[[ -b ${file} ]]

## True if file exists and is a character special file.
[[ -c ${file} ]]

## True if file exists and is a directory.
[[ -d ${file} ]]

## True if file exists.
[[ -e ${file} ]]

## True if file exists and is a regular file.
[[ -f ${file} ]]

## True if file exists and is a symbolic link.
[[ -h ${file} ]]

## True if file exists and is readable.
[[ -r ${file} ]]

## True if file exists and has a size greater than zero.
[[ -s ${file} ]]

## True if file exists and is writable.
[[ -w ${file} ]]

## True if file exists and is executable.
[[ -x ${file} ]]

## True if file exists and is a symbolic link.
[[ -L ${file} ]]
Enter fullscreen mode Exit fullscreen mode

String expressions

# True if the shell variable varname is set (has been assigned a value).
[[ -v ${varname} ]]

# True if the length of the string is zero.
[[ -z ${string} ]]

# True if the length of the string is non-zero.
[[ -n ${string} ]]

# True if the strings are equal. = should be used with the test command for POSIX conformance. When used with the [[ command, this performs pattern matching as described above (Compound Commands)
[[ ${string1} == ${string2} ]]

# True if the strings are not equal.
[[ ${string1} != ${string2} ]]

# True if string1 sorts before string2 lexicographically.
[[ ${string1} < ${string2} ]]

# True if string1 sorts after string2 lexicographically.
[[ ${string1} > ${string2} ]]
Enter fullscreen mode Exit fullscreen mode

Arithmetic operators

# Returns true if the numbers are equal
[[ ${arg1} -eq ${arg2} ]]

# Returns true if the numbers are not equal
[[ ${arg1} -ne ${arg2} ]]

# Returns true if arg1 is less than arg2
[[ ${arg1} -lt ${arg2} ]]

# Returns true if arg1 is less than or equal arg2
[[ ${arg1} -le ${arg2} ]]

# Returns true if arg1 is greater than arg2
[[ ${arg1} -gt ${arg2} ]]

# Returns true if arg1 is greater than or equal arg2
[[ ${arg1} -ge ${arg2} ]]

# As with other programming languages you can use AND & OR conditions:
[[ test_case_1 ]] && [[ test_case_2 ]] # And
[[ test_case_1 ]] || [[ test_case_2 ]] # Or
Enter fullscreen mode Exit fullscreen mode

Conditionals

#!/bin/bash

# Bash if statement example

read -p "What is your name? " name

if [[ -z ${name} ]]
then
    echo "Please enter your name!"
else
    echo "Hi there ${name}"
fi
Enter fullscreen mode Exit fullscreen mode

Loops

For loops

#!/bin/bash

users="devdojo, bobby, tony"

for user in ${users}
do
    echo "${user}"
done
Enter fullscreen mode Exit fullscreen mode

While loops

#!/bin/bash

counter=1
while [[ $counter -le 10 ]]
do
    echo $counter
    ((counter++))
done
Enter fullscreen mode Exit fullscreen mode

Until Loops

#!/bin/bash

count=1
until [ $count -gt 10 ]
do
    echo $count
    ((count++))
done
Enter fullscreen mode Exit fullscreen mode

Functions

function function_name() {
    your_commands
}
Enter fullscreen mode Exit fullscreen mode

Example

#!/bin/bash

function hello(){
    echo "Hello World Function!"
}

hello
Enter fullscreen mode Exit fullscreen mode

Conclusion

For a more in-depth explanations check out this online guide here:

Bash Scripting Hands-on Guide

If you want to learn more about Bash Scripting check out this free eBook here:

💡 Introduction to Bash Scripting

If you prefer video content, you could take a look at this mini video crash course here:

Introduction to Bash Scripting Mini Video Crash Course

You can follow me on Twitter at: @bobbyiliev_

Top comments (6)

Collapse
 
abcsxyz profile image
AbcSxyZ

To add some usefull features, pipe | [and eventually other operator to join command (&&, ||)], redirections.

Command substitution is nice too.

And to perform some calucation : $((1 + 1))

Collapse
 
bobbyiliev profile image
Bobby Iliev

Thank you for the great suggestions!

Collapse
 
jonathan_leffler_336f14e5 profile image
Jonathan Leffler

Under Arrays, you have:

# This would output the total number of elements in the array, ... 4:
echo ${my_array[@]}

This is inaccurate. If you used echo "${#my_array[@]}" you get 4. As written, you get value 1 value 2 value 3 value 4, and that's 8 arguments to echo, as you would see if you used printf '%s\n' ${my_array[@]} instead. You'd get 4 arguments if you used printf '%s\n' "${my_array[@]}", and 1 argument if you used printf '%s\n' "${my_array[*]}", but 8 again if you omitted the double quotes with the * notation. Using both printf '%s\n' ${#my_array[*]} and printf '%s\n' ${#my_array[@]} (without double quotes around the array references) also prints 4 both times. Usually, you should use double quotes around array references.

Collapse
 
bobbyiliev profile image
Bobby Iliev

Thank you for bringing this up!

Indeed I've missed the # sign in the example for getting the lenght of the array. I've added it now.

The printf examples that you've show are really great!

Collapse
 
vannijnatten profile image
Jos van Nijnatten

I would like to add 1) string replacement via ${var/pattern/replacement} or removal at start or end, 2) fifo objects using <(command-with-output), 3) the ways to pipe from ‘find’ (-print0) or ‘grep’(-null) to ‘xargs’(-0), 4) tools such as find, grep, sed, awk, xargs, cut, tr, etc (not strictly bash, these last two). Otherwise, yea probs all you need. Well done!

Collapse
 
lexplt profile image
Alexandre Plt • Edited

Shebang option 2 should be preferred for systems were bash isn't in /bin, that gives a much better portability!

I would also add that there is a huge difference between , and [[ ]] which is a syntactic element of bash, better than the [ command, which you would usually use most of the time.