Getting Started

hello.sh

#!/bin/bash VAR="world" echo "Hello $VAR!" # => Hello world!

Execute script

$ bash hello.sh

Variables

NAME="John" echo ${NAME} # => John (variable) echo $NAME # => John (variable) echo "$NAME" # => John (variable) echo '$NAME' # => $NAME (literal)

Comments

# This is an inline Bash comment. : ' This is a very neat Bash comment '

Bash Parameters

Parameters

Expression Description
$1 ... $9 Parameter 1 ... 9
$0 Name of the script itself
$# Number of parameters
$$ Process ID of the shell
$* All parameters
$@ All parameters, starting from first

Brace Expansion

echo {A,B}.js
Expression Description
{A,B} Same as A B
{A,B}.js Same as A.js B.js
{1..5} Same as 1 2 3 4 5

Parameter Expansion

Syntax

Code Description
${FOO%suffix} Remove suffix
${FOO#prefix} Remove prefix
${FOO/from/to} Replace first match
${FOO//from/to} Replace all
${#FOO} Length of $FOO

Substitution

echo ${food:-Cake} #=> $food or "Cake"
STR="/path/to/foo.cpp" echo ${STR%.cpp} # /path/to/foo echo ${STR%/*} # /path/to echo ${STR##*.} # cpp (extension) echo ${STR##*/} # foo.cpp (basepath) echo ${STR/foo/bar} # /path/to/bar.cpp

Slicing

name="John" echo ${name} # => John echo ${name:0:2} # => Jo echo ${name::2} # => Jo echo ${name:(-1)} # => n echo ${name:(-2)} # => hn

Bash Arrays

Defining Arrays

Fruits=('Apple' 'Banana' 'Orange') Fruits[0]="Apple" Fruits[1]="Banana" Fruits[2]="Orange"

Indexing

Expression Description
${Fruits[0]} First element
${Fruits[-1]} Last element
${Fruits[@]} All elements
${#Fruits[@]} Total count
${!Fruits[@]} All keys

Iteration

Fruits=('Apple' 'Banana' 'Orange') for e in "${Fruits[@]}"; do echo $e done

Conditionals

Integer Conditions

Condition Description
[[ NUM -eq NUM ]] Equal
[[ NUM -ne NUM ]] Not equal
[[ NUM -lt NUM ]] Less than
[[ NUM -le NUM ]] Less than or equal
[[ NUM -gt NUM ]] Greater than

String Conditions

Condition Description
[[ -z STR ]] Empty string
[[ -n STR ]] Not empty string
[[ STR == STR ]] Equal
[[ STR != STR ]] Not equal
[[ STR =~ STR ]] Regex pattern

File Conditions

Condition Description
[[ -e FILE ]] Exists
[[ -d FILE ]] Directory
[[ -f FILE ]] File
[[ -r FILE ]] Readable
[[ -w FILE ]] Writable

Loops

Basic For Loop

for i in /etc/rc.*; do echo $i done

C-like For Loop

for ((i = 0 ; i < 100 ; i++)); do echo $i done

Range

for i in {1..5}; do echo "Welcome $i" done

Step

for i in {5..50..5}; do echo "Welcome $i" done

Infinite Loop

while true; do # some code here done

Read File Line by Line

cat file.txt | while read line; do echo $line done

Functions

Defining Functions

myfunc() { echo "hello $1" } # Alternative syntax function myfunc() { echo "hello $1" } myfunc "John"

Return Values

myfunc() { local myresult='some value' echo $myresult } result="$(myfunc)"

Throwing Errors

myfunc() { return 1 } if myfunc; then echo "success" else echo "failure" fi

Input/Output

Redirection

python hello.py > output.txt # stdout to (file) python hello.py >> output.txt # stdout to (file), append python hello.py 2> error.log # stderr to (file) python hello.py 2>&1 # stderr to stdout python hello.py 2>/dev/null # stderr to (null) python hello.py &>/dev/null # stdout and stderr to (null)

Reading Input

echo -n "Proceed? [y/n]: " read ans echo $ans

Heredoc

cat <

Printf

printf "Hello %s, I'm %s" Sven Olga #=> "Hello Sven, I'm Olga printf "1 + 1 = %d" 2 #=> "1 + 1 = 2"

Miscellaneous

Arithmetic

$((a + 200)) # Add 200 to $a $(($RANDOM%200)) # Random number 0..199

Script Directory

DIR="${0%/*}"

Go to Previous Directory

pwd # /home/user/foo cd bar/ pwd # /home/user/foo/bar cd - pwd # /home/user/foo

Check Command Result

if ping -c 1 google.com; then echo "Your internet connection seems to be working" fi

Strict Mode

set -euo pipefail IFS=$'\n\t'

Debug Mode

#!/bin/bash set -x # Enable debug mode # code to execute here set +x # Disable debug mode