Bash Cheat Sheet
[toc]
Getting started
#!/bin/bash
echo "Hello World!"
[j@master bash]$ cat hello.sh
#!/bin/bash
echo "Hello World!"
[j@master bash]$ chmod +x hello.sh
[j@master bash]$ ./hello.sh
Hello World!
Variables
A variable in bash can contain a number, a character, a string of characters
#!/bin/bash
STR="Hello World!" #No space before/after "="
echo $STR
Local variable
#!/bin/bash
HELLO=Hello
function hello {
local HELLO=World
echo $HELLO
}
echo $HELLO #print "Hello"
hello #invoke function hello and print "World"
echo $HELLO #Print "Hello"
Special Shell Variables
Variable | Meaning |
---|---|
$0 |
Filename of script |
$1 |
Positional parameter #1 |
$2 - $9 |
Positional parameters #2 - #9 |
${10} |
Positional parameter #10 |
$# |
Number of positional parameters |
"$*" |
All the positional parameters (as a single word) * |
"$@" |
All the positional parameters (as separate strings) |
${#*} |
Number of positional parameters |
${#@} |
Number of positional parameters |
$? |
Return value |
$$ |
Process ID (PID) of script |
$- |
Flags passed to script (using set) |
$_ |
Last argument of previous command |
$! |
Process ID (PID) of last job run in background |
Conditional expressions and if
statements
if
if test-commands; then
consequent-commands;
[elif more-test-commands; then
more-consequents;]
[else
alternate-consequents;]
fi
#!/bin/bash
if [ "$1" == "yes" ];then
echo yes
elif [ "$1" == "no" ];then
echo no
else
echo "Please input yes or no"
fi
case
#!/bin/bash
show_help(){
echo "Usage: ${0##*/} [-h|--help] [-v|--verbose] [-l|--lines number] FILE... "
}
while (( "$#" )); do
case $1 in
-h|--help)
show_help
exit
;;
-l|--lines)
if [ "$2" ] && [ ${2:0:1} != "-" ]; then
number=$2
shift
else
echo "Option -l|--lines needs an argument"
show_help
exit 1
fi
;;
-v|--verbose)
verbose=1
;;
-?*)
echo "Option $1 is not supported."
show_help
exit 1
;;
*)
break
esac
shift
done
select
The select construct, adopted from the Korn Shell, is yet another tool for building menus
select variable [in list]
do
command...
break
done
((..))
(( expression ))
(( 5 > 4 )) # true
echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0
(( 5 > 9 )) # false
echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1
i=1
(( i++ )) # i=2
a=$(( 3+6 )) #a=9
let a++ #a=10 now
[[…]]
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the conditional expression expression
#!/bin/bash
file=/etc/passwd
if [[ -e $file ]]; then
echo "Password file exists."
fi
Expression
( expression ) #Returns the value of expression
! expression #True if expression is false
expression1 && expression2 #True if both expression1 and expression2 are true
expression1 || expression2 #True if either expression1 or expression2 is true
Test Operators
Arithmetic Comparison
Operator | meaning | example |
---|---|---|
-eq | Equal to | if [ “$a” -eq “$b” ] |
if [[ $a -eq $b ]] | ||
-ne | Not equal to | if [ “$a” -ne “$b” ] |
-lt | Less than | if [ “$a” -lt “$b” ] |
-le | Less than or equal to | if [ “$a” -le “$b” ] |
-gt | Greater than | if [ “$a” -gt “$b” ] |
-ge | Greater than or equal to | if [ “$a” -ge “$b” ] |
Arithmetic Tests using (( ))
> |
Greater than |
---|---|
>= |
Greater than or equal to |
< |
Less than |
<= |
Less than or equal to |
Example:
#!/bin/bash
var1=5
var2=2
if (( $var1 > $var2 )); then
echo "$var1 is greater than $var2"
fi
string comparison
Operator | Meaning | Example |
---|---|---|
= | Equal to | if [ “$a” = “$b” ] |
== | Equal to | if [ “$a” == “$b” ] |
!= | Not equal to | if [ “$a” != “$b” ] |
\< | Less than | if [[ “$a” < “$b” ]] |
if [ “$a” \< “$b” ] | ||
\> | Greater than | if [[ “$a” > “$b” ]] |
if [ “$a” > “$b” ] | ||
-z | String is empty | if [ -z “$String” ] |
-n | String is not empty | if [ -n “$String” ] |
File test
if [[ -e "file.txt" ]]; then
: # do nothing
fi
Operator | Tests Whether | —– | Operator | Tests Whether |
---|---|---|---|---|
-e |
File exists | -s |
File is not zero size | |
-f |
File is a regular file | |||
-d |
File is a directory | -r |
File has read permission | |
-h |
File is a symbolic link | -w |
File has write permission | |
-L |
File is a symbolic link | -x |
File has execute permission | |
-b |
File is a block device | |||
-c |
File is a character device | -g |
sgid flag set | |
-p |
File is a pipe | -u |
suid flag set | |
-S |
File is a socket | -k |
“sticky bit” set | |
-t |
File is associated with a terminal | |||
-N |
File modified since it was last read | F1 -nt F2 |
File F1 is newer than F2 * | |
-O |
You own the file | F1 -ot F2 |
File F1 is older than F2 * | |
-G |
Group id of file same as yours | F1 -ef F2 |
Files F1 and F2 are hard links to the same file * | |
! |
NOT (inverts sense of above tests) |
Loop for , while and until
for
#!/bin/bash
for i in $( ls ); do
echo item: $i
done
#!/bin/bash
for i in `seq 1 10`;
do
echo $i
done
while
The while executes a piece of code if the control expression is true, and only stops when it is false (or a explicit break is found within the executed code
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1
done
until
The until loop is almost equal to the while loop, except that the code is executed while the control expression evaluates to false
#!/bin/bash
COUNTER=20
until [ $COUNTER -lt 10 ]; do
echo COUNTER $COUNTER
let COUNTER-=1
done
Functions
Functions with parameters sample
#!/bin/bash
function quit {
exit
}
function e {
echo $1
}
e Hello
e World
quit
echo foo
Return value
#!/bin/bash
myfunc() {
local myresult='some value'
echo $myresult
}
result="$(myfunc)"
Redirection
Files | Meaning | File descriptor |
---|---|---|
stdin | the keyboard | 0 |
stdout | the screen | 1 |
stderr | error messages output to the screen | 2 |
2>filename # Redirect stderr to file "filename."
2>>filename # Redirect and append stderr to file "filename."
2>&1 # Redirects stderr to stdout.
&>filename # Redirect both stdout and stderr to file "filename."
&>/dev/null #Redirect both stdout and stderr to null
#!/bin/bash
#read lines into array
myarr=()
while read line; do
myarr+=("$line")
done <file.txt
Here Documents
[j@master bash]$ cat <<End-of-message
> -------------------------------------
> This is line 1 of the message.
> This is line 2 of the message.
> This is line 3 of the message.
> This is line 4 of the message.
> This is the last line of the message.
> -------------------------------------
> End-of-message
-------------------------------------
This is line 1 of the message.
This is line 2 of the message.
This is line 3 of the message.
This is line 4 of the message.
This is the last line of the message.
-------------------------------------
[j@master bash]$
Here strings
[j@master bash]$ read first second <<< "hello world"
[j@master bash]$ echo $second $first
world hello
Array and Dictionary
myarr=() #Make an empty array
myarr=(a b c 3 2 1) #Initialize an array
${myarr[4]} #Getting 5th element
${myarr[@]} #Getting all emements
${!myarr[@]} #Getting indices
${#myarr[@]} #Getting length
myarr[2]=3 #Modify 3nd element
myarr+=(x y z) #Append elements
myarr=( $(ls) ) #Save `ls` out as an array
${myarr[@]:s:n} #Retrieve n elements beginning at index s
unset myarr[0] #Destroy 1st element
unset myarr #Remove the entire array
See more Bash array
Regular Expressions
. | dot | matches any one character, except a newline |
? | question mark | matches zero or one of the previous RE |
* | asterisk | matches zero or N numbers of repeats of the preceding character |
+ | The plus | matches one or more of the previous RE |
^ | caret | matches the beginning of a line |
$ | dollar sign | at the end of an RE matches the end of a line |
[…] | Brackets | enclose a set of characters to match in a single RE |
[xyz] | matches x OR y OR z | |
[a-z0-9] | matches any single lowercase letter or any digit | |
\$ | matches “$” | |
\<the\> | matches “the” but not “them” ,”other” | |
[0-9]{5} | matches file digits | |
( ) | Parentheses | enclose a group of REs |
| | or | matches any of a set of alternate characters |
postfix
[:alnum:] | matches alphabetic or numeric characters. This is equivalent to **A-Za-z0-9** |
[:alpha:] | This is equivalent to **A-Za-z** |
[:blank:] | matches a space or a tab |
[:cntrl:] | matches control characters |
[:digit:] | This is equivalent to **0-9** |
[:graph:] | Matches characters in the range of ASCII 33 - 126. This is the same as **[:print:]** , below, but excluding the space character |
[:lower:] | matches lowercase alphabetic characters. This is equivalent to **a-z** |
[:print:] | Matches characters in the range of ASCII 32 - 126. This is the same as **[:graph:]** , above, but adding the space character. |
[:space:] | matches whitespace characters (space and horizontal tab) |
[:upper:] | matches uppercase alphabetic characters. This is equivalent to **A-Z** |
[:xdigit:] | matches hexadecimal digits. This is equivalent to **0-9A-Fa-f** |
#!/bin/bash
# 3-5 lower letters + 5 digits + @ + something.com
REGEX='^([a-z]{3,5}[0-9]{5})\@(.+\.com)$'
if [[ $1 =~ $REGEX ]]; then
echo "Username is ${BASH_REMATCH[1]}"
echo "Domain is ${BASH_REMATCH[2]}"
else
echo "Not a supported mail address "
fi
[j@master bash]$ ./1.sh user12345@gmail.com
Username is user12345
Domain is gmail.com
[j@master bash]$
[j@master bash]$ ./1.sh user123456@gmail.com
Not a supported mail address
Shell expansions
Brace Expansion
bash$ echo a{d,c,b}e
ade ace abe
Parameter Substitution and Expansion
Expression | Meaning |
---|---|
${var} |
Value of *var* (same as *$var* ) |
${var-$DEFAULT} |
If *var* not set, evaluate expression as *$DEFAULT* * |
${var:-$DEFAULT} |
If *var* not set or is empty, evaluate expression as *$DEFAULT* * |
${var=$DEFAULT} |
If *var* not set, evaluate expression as *$DEFAULT* * |
${var:=$DEFAULT} |
If *var* not set or is empty, evaluate expression as *$DEFAULT* * |
${var+$OTHER} |
If *var* set, evaluate expression as *$OTHER* , otherwise as null string |
${var:+$OTHER} |
If *var* set, evaluate expression as *$OTHER* , otherwise as null string |
${var?$ERR_MSG} |
If *var* not set, print *$ERR_MSG* and abort script with an exit status of 1.* |
${var:?$ERR_MSG} |
If *var* not set, print *$ERR_MSG* and abort script with an exit status of 1.* |
${!varprefix*} |
Matches all previously declared variables beginning with *varprefix* |
${!varprefix@} |
Matches all previously declared variables beginning with *varprefix* |
**** If *var*
*is set, evaluate the expression as *$var*
with no side-effects.
#01 If parameter not set, use default
var1=1
var2=2
# var3 is unset.
echo ${var1-$var2} # 1
echo ${var3-$var2} # 2
#02 If parameter not set, set it to default
echo ${var=abc} # abc
echo ${var=xyz} # abc
# $var had already been set to abc, so it did not change.
#3 If parameter set, use alt_value, else use null string
a=${param1+xyz} # param1 is not set
echo "a = $a" # so a =
param2= # param2 is set
a=${param2+xyz}
echo "a = $a" #so a = xyz
#4 If parameter set, use it, else print err_msg and abort the script with an exit status of 1
#!/bin/bash
# usage-message.sh
: ${1?"Usage: $0 ARGUMENT"}
# Script exits here if command-line parameter absent,
#+ with following error message.
# usage-message.sh: 1: Usage: usage-message.sh ARGUMENT
String Operations
Expression | Meaning |
---|---|
${#string} |
Length of *$string* |
${string:position} |
Extract substring from *$string* at *$position* |
${string:position:length} |
Extract *$length* characters substring from *$string* at *$position* [zero-indexed, first character is at position 0] |
${string#substring} |
Strip shortest match of *$substring* from front of *$string* |
${string##substring} |
Strip longest match of *$substring* from front of *$string* |
${string%substring} |
Strip shortest match of *$substring* from back of *$string* |
${string%%substring} |
Strip longest match of *$substring* from back of *$string* |
${string/substring/replacement} |
Replace first match of *$substring* with *$replacement* |
${string//substring/replacement} |
Replace all matches of *$substring* with *$replacement* |
${string/#substring/replacement} |
If *$substring* matches front end of *$string* , substitute *$replacement* for *$substring* |
${string/%substring/replacement} |
If *$substring* matches back end of *$string* , substitute *$replacement* for *$substring* |
***** Where *$substring*
is a Regular Expression
#1 ${#string}
a="abc"
echo ${#a} # get 3
#2 ${string:position}
a="abc123"
echo ${a:3} #get 123
#3 ${string#substring}
a="000123"
echo ${a#0} # get 00123
echo ${a##+(0)} # get 123
#4 ${string%substring}
a="123000"
echo ${a%0} # get 12300
echo ${a%%+(0)} #get 123
#5 ${var/Pattern/Replacement}
a="a123a"
echo ${a/a/A} #get A123a
echo ${a//a/A} #get A123A
#6 ${var/#Pattern/Replacement} ${var/%Pattern/Replacement}
[j@master bash]$ a="X000X"
[j@master bash]$ echo ${a/#X/Y}
Y000X
[j@master bash]$ echo ${a/%X/Y}
X000Y
MISC
read user input
#!/bin/bash
echo Please, enter your firstname and lastname
read FN LN
echo "Hi! $LN, $FN !"
Trap error
#! /bin/bash
err_report() {
echo "Error on line $1"
}
trap 'err_report $LINENO' ERR
echo hello | grep foo # This is line number 9
$ ./test.sh
Error on line 9
Trap on EXIT
#!/bin/bash
trap 'echo Variable a = $a ' EXIT
a=11
a=22
$ ./test.sh
Variable a = 22
Logging
#!/bin/bash
exec >> logfile.log 2>&1
date
set -x