Advanced Bash-Scripting Guide
sed
awk
Internal Variables
#current parent pid
$$
#last background process pid
$!
#last exit status
$?
#current instance pid, Bash 4.x above.
$BASHPID
Arithmetic Expansion
a=12
b=$(($a + 10))
b=`expr $a + 1`
b=$(expr $a + 1)
let b=$a+3
#let b=$a + 3 #incorrect
let "b = $a + 3"
declare -i b=$a+$a
Manipulating Strings
- String is a number
if [[ $var =~ ^-?[0-9]+$ ]]; then
echo "$var is a number"
fi
if [[ ! $var =~ ^-?[0-9]+$ ]]; then
echo "$var is not a number"
fi
- Find String between two words or characters
var="Hello there are (123340) and (123)"
#last string between '(' and ')'.
substr=$( echo $var | sed 's/.*(\(.*\)).*/\1/' )
#String between '(' and ')'.
substr=$( echo $var | awk -v FS="(\(|\))" '{print $2 " " $4}' )
#String between 'there' and 'and'.
substr=$( echo $var | awk -v FS="(there|and)" '{print $2}' )
#String between 'there' and 'and'.
substr=$( echo $var | sed 's/.*there\(.*\)and.*/\1/' )
#String between 'there' and 'and'.
substr=$( echo $var | grep -o -P '(?<=there).*(?=and)' )
Loop
- read variables
#read from file
echo "123, abc, hello world!" > /tmp/test
echo "12 43, ddd, !" >> /tmp/test
while IFS=',' read var1 var2 var3
do
echo "var1=$var1 var2=$var2 var3=$var3"
done < "/tmp/test"
#read from variable
x="one, two, three"
while IFS=',' read var1 var2 var3
do
echo "var1=$var1 var2=$var2 var3=$var3"
done <<< $x
- iterate IP address
#iterate class C ip address
for i in 192.168.100.{1..10}
do
echo "$i"
done
#iterate class B ip address
for x in 192.168.{1..5}
do
for i in $x.{1..10}
do
echo "$i"
done
done
- infinite while loop
while :
do
echo "infinite loops [ CTRL+C to stop]"
sleep 5
done
Array
# Simple array
arrayA=( Mon Tue Wed Thu Fri Sat Sun )
echo "${!arrayA[*]}" # 0 1 2 3 4 5 6
echo "${#arrayA[*]}" # 7
echo "${arrayA[*]}" # Mon Tue Wed Thu Fri Sat Sun
echo "${!arrayA[@]}" # 0 1 2 3 4 5 6
echo "${#arrayA[@]}" # 7
echo "${arrayA[@]}" # Mon Tue Wed Thu Fri Sat Sun
echo "${arrayA[2]}" # Wed
echo "$arrayA" # Mon
echo "${arrayA[20]}" # null
arrayA=( one two )
echo "${arrayA[*]}" # one two
arrayA+=( three "four" )
echo "${arrayA[*]}" # one two three four
# Key/Value
declare -A arrayB=( ["Mon"]="Monday" ["Tue"]="Tuesday"
["Wed"]="Wednesday" ["Thu"]="Thursday" ["Fri"]="Friday"
["Sat"]="Saturday" ["Sun"]="Sunday" )
echo "${!arrayB[*]}" # Thu Tue Wed Mon Fri Sat Sun
echo "${#arrayB[*]}" # 7
echo "${arrayB[*]}" # Thursday Tuesday Wednesday Monday Friday Saturday Sunday
echo "${!arrayB[@]}" # Thu Tue Wed Mon Fri Sat Sun
echo "${#arrayB[@]}" # 7
echo "${arrayB[@]}" # Thursday Tuesday Wednesday Monday Friday Saturday Sunday
echo "${arrayB[2]}" # null
echo "$arrayB" # null
echo "${arrayB["Tue"]}" # Tuesday
declare -A arrayB=( ["one"]=1 ["two"]="2" )
echo "${!arrayB[*]}" # one two
echo "${arrayB[*]}" # 1 2
arrayB+=( ["three"]="3" ["four"]=4 )
echo "${!arrayB[*]}" # four one two three
echo "${arrayB[*]}" # 4 1 2 3
arrayB+=( ["four"]="aa" ["five"]="5a1c" )
echo "${!arrayB[*]}" # four one five two three
echo "${arrayB[*]}" # 4aa 1 5a1c 2 3
I/O redirection
Forking Processes
pid_perfix="/tmp/proc-"
function doSomething(){
local pid_file="$pid_perfix$BASHPID"
echo "this is task $1 : $pid_file " > $pid_file
sleep 5
}
w_pid=""
for task in {1..5}
do
doSomething $task &
w_pid+="$! "
sleep 1
done
for p in $w_pid
do
wait $p
done
#clean up
for p in $w_pid
do
#del pid file
rm "$pid_perfix$p"
done
exit 0