bash script programming

Bash header

#!/bin/bash -

#

# Add "-e" Mean Exit Immediately If A Command Exits With A Non-Zero Status.

# Add "-v  Mean Prints Shell Input Lines As They Are Read.

# Add "-x  Mean Print Command xTraces Before Executing Command.

#

# This Script ...

# ...

#


Run the bash script

bash -x myscript.sh

Or

bash -vx myscript.sh

Or

bash -evx myscript.sh


Test If We Have Arguments, Exit With Warning If Without Argument

if [ $# -eq 0 ]; then

  echo ""

  echo "Usage"

  echo "    `basename $0` Arg1 [Arg2]"

  echo "    Arg1 = foo | bar"

  echo ""

  echo "Example:"

  echo "    `basename $0` foo"

  echo "    `basename $0` bar"

  # Return With Non-Zero Status (Indicating Error)

  exit 1

fi


Test If We Have Arguments, And Not More Than 2 Argument, Exit With Warning If We Don't

if [[ $# -eq 0 || $# -gt 2 ]]; then

  echo ""

  echo "Usage"

  echo "    `basename $0` Arg1 [Arg2]"

  echo "    Arg1 = foo | bar"

  echo ""

  echo "Example:"

  echo "    `basename $0` foo"

  echo "    `basename $0` bar"

  # Return With Non-Zero Status (Indicating Error)

  exit 1

fi


# -eq

# is equal to

# if [ "$a" -eq "$b" ]

#

# -ne

# is not equal to

# if [ "$a" -ne "$b" ]

#

# -gt

# is greater than

# if [ "$a" -gt "$b" ]

#

# -ge

# is greater than or equal to

# if [ "$a" -ge "$b" ]

#

# -lt

# is less than

# if [ "$a" -lt "$b" ]

#

# -le

# is less than or equal to

# if [ "$a" -le "$b" ]


Bash Sample

# Setup String Variable

strHome="/home/build/myproject"

strDate=`date '+%Y%m%d_%H%M'`

strArg1=$1


# Redirect Stdout/Stderr To File

exec 1>./$strDate.txt 2>&1


# Redirect Stdout/Stderr To File And Screen

exec > >(tee $strDate.txt) 2>&1


# Log With Date Prompt

function log() {

  echo `date '+%Y%m%d_%H%M'` : "$@"

}


log "----------------------------------------"

log ">>> start: git clone"

cd $strHome

mkdir ${strDate}_${strArg1}

cd ${strDate}_${strArg1}

git clone ssh://user@100.100.100.100/home/repo/git/myproject

log "<<< done: git clone"

log "----------------------------------------"


log "----------------------------------------"

log ">>> start: make at $MAKETOP/usr/src"

cd ${strDate}_${strArg1}

make

log "<<< done: make at $MAKETOP/usr/src"

log "----------------------------------------"


Local variable add keyword "local"

function hello {

  local HELLO=World

  echo $HELLO

}


IF TEMPLATE

#    if <LIST>; then

#      <LIST>

#    elif <LIST>; then

#      <LIST>

#    else

#      <LIST>

#    fi

#

#-a file

#    True if file exists.

#-b file

#    True if file exists and is a block special file.

#-c file

#    True if file exists and is a character special file.

#-d file

#    True if file exists and is a directory.

#-e file

#    True if file exists.

#-f file

#    True if file exists and is a regular file.

#-g file

#    True if file exists and its set-group-id bit is set.

#-h file

#    True if file exists and is a symbolic link.

#-k file

#    True if file exists and its "sticky" bit is set.

#-p file

#    True if file exists and is a named pipe (FIFO).

#-r file

#    True if file exists and is readable.

#-s file

#    True if file exists and has a size greater than zero.

#-t fd

#    True if file descriptor fd is open and refers to a terminal.

#-u file

#    True if file exists and its set-user-id bit is set.

#-w file

#    True if file exists and is writable.

#-x file

#    True if file exists and is executable.

#-O file

#    True if file exists and is owned by the effective user id.

#-G file

#    True if file exists and is owned by the effective group id.

#-L file

#    True if file exists and is a symbolic link.

#-S file

#    True if file exists and is a socket.

#-N file

#    True if file exists and has been modified since it was last read.

#file1 -nt file2

#    True if file1 is newer (according to modification date) than file2.

#file1 -ot file2

#    True if file1 is older than file2.

#file1 -ef file2

#    True if file1 and file2 have the same device and inode numbers.

#-o optname

#    True if shell option optname is enabled. The list of options appears in the description of the `-o' option to set.

#-z string

#    True if the length of string is zero. -n string

#    True if the length of string is non-zero.

#string1 == string2

#    True if the strings are equal. `=' can be used in place of `=='.

#string1 != string2

#    True if the strings are not equal.

#string1 < string2

#    True if string1 sorts before string2 lexicographically in the current locale.

#string1 > string2

#    True if string1 sorts after string2 lexicographically in the current locale.

#arg1 OP arg2

#    OP is one of "-eq", "-ne", "-lt", "-le", "-gt", or "-ge".


Check String

if [ -z ${MAKETOP} ] ; then

  echo "MAKETOP = nothing"

else

  echo "MAKETOP = ${MAKETOP}"

fi


Check Argument Exist Or Not

if [ -z $2 ] ; then

  strFromCommit="HEAD~1"

else

  strFromCommit="HEAD~"$2

fi


Check If A Specific User Exists In /etc/passwd

if grep ^myuser: /etc/passwd >/dev/null 2>&1; then

  echo "Yes, it seems I am real"

else

  echo "Uh am I a ghost ?"

fi


FOR TEMPLATE

for (( <EXPR1> ; <EXPR2> ; <EXPR3> )); do

    <LIST>

done


# as a special case: without semicolon after ((...))

for (( <EXPR1> ; <EXPR2> ; <EXPR3> )) do

  <LIST>

done


# alternative, historical and undocumented syntax

for (( <EXPR1> ; <EXPR2> ; <EXPR3> )) {

  <LIST>

}


Loop Through A Set Of Strings

for m in Apple Sony Panasonic "Hewlett Packard" Nokia

do

  echo "Manufacturer is:" $m

done


Loop Through A Set Of Strings

FilePath=(

  "/tmp/path1/"    #FilePath[0]

  "/tmp/path2/"    #FilePath[1]

)

for Path in "${FilePath[@]}"

do

  echo "$Path"

done


Loop 5 times

for i in $(seq 1 5); do echo -n "HelloWorld${i} "; done


Loop 5 times

for ((x = 0 ; x <= 4 ; x++)); do

  echo "Counter: $x"

done


Loop With Break

# echo -n "$myloop"    # "-n" mean without newline

for myloop in 1 2 3 4 5

do

  echo "$myloop"

  if [ "$myloop" -eq 3 ]; then

      break

  fi

done


Loop Through The Arguments Passed To A Function

printArg ()

{

  for ARG in "$@"; do echo $ARG; done

}

Then run it at bash

printArg arg1 arg2 arg3


Function convert decimal to binary

function toBin {

  typeset m=$1 n=2 x='x[(n*=2)>m]'

  for ((x = x; n /= 2;)); do

    printf %d $(( m & n && 1))

  done

}

Then run it at bash

toBin 12


CASE TEMPLATE

#    case <WORD> in

#      [(] <PATTERN1> ) <LIST1> ;; # or ;& or ;;& in Bash 4

#      [(] <PATTERN2> ) <LIST2> ;;

#      [(] <PATTERN3> | <PATTERN4> ) <LIST3-4> ;;

#      ...

#      [(] <PATTERNn>) <LISTn> [;;]

#    esac

fruit=$1

case $fruit in

  apple)

    echo 'I like apple !'

      ;;

  orange | banana)

    echo $'Eeeks! I don\'t like those!\nGo away!'

    exit 1

    ;;

  *)

    echo 'Unknown fruit'

esac


Convert hex to dec

echo $((0x5c6))


Convert dec to hex

printf '%x\n' 1478

Or

printf '%#x' 100


Repeatly printf

for i in seq 1 100; do printf '%x\n' $i done


Find 2 to power of 14, 2^14

echo $(( 1<<14 ))