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