Bash Scripting Cheatsheet
Bash Scripting Cheatsheet
cheatsheet
Introduction Variables
name="John"
This is a quick reference to getting started
echo $name # see below
with Bash scripting. echo "$name"
echo "${name}!"
Learn bash in y minutes
(learnxinyminutes.com)
Generally quote your variables unless they contain
wildcards to expand or command fragments.
Bash Guide
(mywiki.wooledge.org)
wildcard="*.txt"
Bash Hackers Wiki options="iv"
cp -$options $wildcard /tmp
(wiki.bash-hackers.org)
Shell execution
Functions
get_name() {
Brace expansion
echo "John"
}
echo {A,B}.js
echo "You are $(get_name)"
{A,B} Same as A B
See: Functions
{A,B}.js Same as A.js B.js
{1..5} Same as 1 2 3 4 5
{{1..3},{7..9}} Same as 1 2 3 7 8 9
Conditionals
See: Conditionals
Parameter expansions
Basics Indirection
name="John" name=joe
echo "${name}" pointer=name
echo "${name/J/j}" #=> "john" (substitution) echo ${!pointer}
echo "${name:0:2}" #=> "Jo" (slicing) joe
echo "${name::2}" #=> "Jo" (slicing)
echo "${name::-1}" #=> "Joh" (slicing)
echo "${name:(-1)}" #=> "n" (slicing from right)
echo "${name:(-2):1}" #=> "h" (slicing from right)
echo "${food:-Cake}" #=> $food or "Cake" Substitution
str="Hello world"
echo "${str:6:5}" # "world"
echo "${str: -5:5}" # "world"
Comments
src="/path/to/foo.cpp"
base=${src##*/} #=> "foo.cpp" (basepath) # Single line comment
dir=${src%$base} #=> "/path/to/" (dirpath)
: '
This is a
multi line
comment
Prefix name expansion '
prefix_a=one
prefix_b=two
echo ${!prefix_*} # all variables names starting with `prefix_
prefix_a prefix_b
Substrings Default values
${foo:0:3} Substring (position, length) ${foo:-val} $foo, or val if unset (or null)
${foo:(-3):3} Substring from the right ${foo:=val} Set $foo to val if unset (or
null)
Length null)
str="HELLO WORLD!"
echo "${str,}" #=> "hELLO WORLD!" (lowercase 1st letter)
echo "${str,,}" #=> "hello world!" (all lowercase)
str="hello world!"
echo "${str^}" #=> "Hello world!" (uppercase 1st letter)
echo "${str^^}" #=> "HELLO WORLD!" (all uppercase)
Loops
for i in {5..50..5}; do
C-like for loop echo "Welcome $i"
done
Functions
myfunc() { myfunc() {
echo "hello $1" return 1
} }
myfunc "John"
Arguments
Returning values
$# Number of arguments
myfunc() {
$* All positional arguments (as a single word)
local myresult='some value'
echo "$myresult"
$@ All positional arguments (as separate strings)
}
$1 First argument
result=$(myfunc)
$_ Last argument of the previous command
[[ -e FILE ]] Exists
Note that [[ is actually a command/program that
returns either 0 (true) or 1 (false). Any program that
[[ -r FILE ]] Readable
obeys the same logic (like all base utils, such as
grep(1) or ping(1)) can be used as condition, see [[ -h FILE ]] Symlink
examples.
[[ -d FILE ]] Directory
[[ -z STRING ]] Empty string
[[ -w FILE ]] Writable
[[ -n STRING ]] Not empty string
[[ -s FILE ]] Size is > 0 bytes
[[ STRING == STRING ]] Equal
[[ -f FILE ]] File
[[ STRING != STRING ]] Not Equal
[[ -x FILE ]] Executable
[[ NUM -eq NUM ]] Equal
[[ FILE1 -nt FILE2 ]] 1 is more recent than
[[ NUM -ne NUM ]] Not equal 2
[[ NUM -lt NUM ]] Less than [[ FILE1 -ot FILE2 ]] 2 is more recent than
1
[[ NUM -le NUM ]] Less than or equal
[[ FILE1 -ef FILE2 ]] Same files
[[ NUM -gt NUM ]] Greater than
More conditions
[[ -o noclobber ]] If OPTIONNAME is
enabled
[[ ! EXPR ]] Not
[[ X && Y ]] And
[[ X || Y ]] Or
Example
# String
if [[ -z "$string" ]]; then
echo "String is empty"
elif [[ -n "$string" ]]; then
echo "String is not empty"
else
echo "This never happens"
fi
# Combinations
if [[ X && Y ]]; then
...
fi
# Equal
if [[ "$A" == "$B" ]]
# Regex
if [[ "A" =~ . ]]
Arrays
Dictionaries
Options
Options Glob options
History
Commands Operations
Miscellaneous
traperr() {
echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO
}
Transform strings
set -o errtrace
trap traperr ERR -c Operations apply to characters not
in the given set
-d Delete characters
Example
source "${0%/*}/../share/foo.sh"
echo "Welcome To Devhints" | tr '[:lower:]' '[:up
WELCOME TO DEVHINTS
Directory of script Special variables
$$ PID of shell
Getting options
$0 Filename of the shell script
while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case
-V | --version ) $_ Last argument of the
echo "$version" previous command
exit
;; ${PIPESTATUS[n]} return value of piped
-s | --string ) commands (array)
shift; string=$1
;; See Special parameters.
-f | --flag )
flag=1
;;
esac; shift; done
if [[ "$1" == '--' ]]; then shift; fi Go to previous directory
pwd # /home/user/foo
cd bar/
Heredoc pwd # /home/user/foo/bar
cd -
pwd # /home/user/foo
cat <<END
hello world
END
Grep check
The -r option disables a peculiar legacy behavior
with backslashes.
if grep -q 'foo' ~/.bash_history; then
echo "You appear to have typed 'foo' in the pas
read -n 1 ans # Just one character fi