2017年3月10日星期五

BASH reference

#!/bin/bash    #tells *nix BASH should be used to run it

Special Parameters
$#    #Store the number of arguments passed from the command line
$1    #first parameter
$?    #Store the exit status of the last executed command
$_    #Print the last argument of the previous command
$$    #Return the process ID of the shell
$!     #Return the process ID of the last executed background process

${#var}    #Number of characters in $var
${#array} #The length of the first element in the array.

${para}  #same as $para. May be used for concatenating variables with strings.
${para-default},${para:-default}   #if para not set, use default
${para=default},${para:=default}    #if para not set, set it to default
${parameter+alt_value}, ${parameter:+alt_value}    #If parameter set, use alt_value, else use null string.
${parameter?err_msg}, ${parameter:?err_msg}If parameter set, use it, else print err_msg and abort the script with an exit status of 1.

The : makes a difference only when parameter has been declared and is null


$*     #* Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable. That is, "$*" is equivalent to "$1c$2c...", where c is the first character of the value of the IFS variable. If IFS is unset, the parameters are separated by spaces. If IFS is null, the parameters are joined without intervening separators.

$@    #@ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" ... If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).

For more details, please check:
http://tldp.org/LDP/abs/html/special-chars.html

[ is a synonym for test command. Even if it is built in to the shell it creates a new process.

[[ is a new improved version of it, which is a keyword, not a program.

Conditional Expression
[expr1 -ne expr2]    #Return true if expr1 is not equal to expr2
[expr1 -eq expr2]    #Return true if expr1 is equal to expr2
[expr1 -gt expr2]    #Return true if expr1 is greater than expr2
[expr1 -ge expr2]    #Return true if expr1 is greater than or equal to expr2
[expr1 -lt expr2]     #Return true if expr1 is less than expr 2
[expr1 -le expr2]    #Return true if expr1 is less than or equal to expr2
[-z  expr]    #Return true if the expression is null or empty
[expr =~ regular_expr]    #Return true if the regular expression is matched.
[expr1 -a expr2],[expr1]&&[expr2]    #Return true if both the expression is and
[expr1 -o expr2],[expr1]||[expr2]   #Return true if either of the expr1 or expr2  is true

[-a filepath],[-e filePath]    #Return true if file exists
[-f  filepath]   #Return true if it is file
[-d directory]    #Return true if it is directory
[-L filepath],[-h filePath]    #Return true if file is a symbolic link
[-S socket]    #Return true if file exists and socket file
[-b filepath]  #Return true if file is a block device
[-c filepath]  #Return true if file is a char device

[-r filepath]   #Return true if file is readable
[-w filepath]    #Return true if file is writable
[-x filepath]    #Return true if file is executable
[-u filepath]    #Return true if SUID is set
[-g filepath]    #Return true if SGID is set
[-k filepath]    #Return true if sticky bit is set
[-s filepath]    #Return true if file exists and has a size greater than 0

Number Notation
echo $((0xFFFF))          #Hex, Display 65535
echo $((032))                 #Octal, Output 26
echo $((2#11111111))  #Binary, Output 255

Frequency Used Command
source filepath    #executes the contents of a script in the current shell



Example: 
 #arithmetic calculation, integer only, output "1"
echo $(( 13 % 3 ))

#floating point calculation
echo "The result is $(bc -l <<< 'scale=2; 100/3')"

#if example
if [ $((1+2)) == 3 ]; then
 echo true
fi

#case example
case "$str" in
  abc)  echo "\$str = abc" ;;
  xyz)  echo "\$str = xyz" ;;
esac

#for example
for i in $( ls ); do
    echo item: $i
done

#while example, Output 0 to 9
count=0
while [[ $count -lt 10 ]]; do
    echo "count: $count"
    count=$(($count+1))
done

#until example, the loop execute until the test expression return true
#Output 0..10
count=0
until [[ $count -gt 10 ]]; do
    echo "count: $count"
    count=$(($count+1))
done

#function example
function quit {
    exit
}
function e {
    echo $1

e Hello
e World
quit

#Shift example
USAGE="Usage: num1 num2 num3 ... numN"

if [ "$#" == "0" ]; then
    echo "$USAGE"
    exit 1
fi

function IsNum
{
    re='^-?[0-9]+$'
    if [[ $1 =~ $re ]] ; then
        return 0
    else
        return 1
    fi
}

result=0

while (( "$#" )); do
    if IsNum $1 ; then
        result=$((result+$1))
    else
        echo "Not a number"
        exit 1
    fi
    shift
done

#select example
OPTIONS="Hello Quit"
select opt in $OPTIONS; do
if [[ "$opt" = "Quit" ]]; then
    echo done
    exit
elif [[ "$opt" = "Hello" ]]; then
    echo Hello World
else
    clear
    echo bad option
fi
done

#Parse input parameter
while [ $# -gt 0 ]; do
    case "$1" in
        -h | --help )
            usage
            exit 0
            ;;
        -g | --debug )
            debug=1
            shift
            ;;
        -- ) # Stop option processing
            shift
            break
            ;;
        * )
            break
            ;;
    esac
done


#Concatenate PATH
echo "Old \$PATH = $PATH"
PATH=${PATH}:/opt/bin
echo "New \$PATH = $PATH"

#Simple backup script
of=/var/backup-$(date +%Y%m%d).tgz
tar -cZf $of ~/backup/

#Check the number of input parameter. If zero, print the usage.
if [[ $# -ne 1]]; then
  echo USAGE: $0 env_file
  exit 1
fi

#execute the script, the script file path is assigned from first parameter.
source "$1"

#Unexpected output found if the variable contains space and mixed with double qoutes
paraNoSpace="-l"
paraWithSpace="-l -a"

ls $paraNoSpace      #treat as ls -l
ls "$paraNoSpace"    #treat as ls -l
ls $paraWithSpace    #treat as ls -l
ls "$paraWithSpace"  #ls: invalid option -- ' '

#Check the return code of the last executed command
#Print the message if it is zero
exitcode=$?
if [[ "${exitcode}" =~ [0] ]]; then
    echo "exitcode was zero"
fi

#Exit, the return code set to 0
$exitNum=0
exit $exitNum

#check the Social Security Number
input=$1
if [[ "$input" =~ "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" ]]
then
  echo "Social Security number."
else
  echo "Not a Social Security number!"
fi

#Check root permission
if ! [ $(id -u) = 0 ]; then
   echo "I am not root!"
   exit 1
fi

#Output "Both equal 0" if expr1 and expr2 are both zero.
if [[ $expr1 -eq 0 ]] && [[ $expr2 -eq 0 ]]; then
    echo "Both equal 0"
fi

#Number comparison
if [$expr1 -lt $expr2]; then
    echo "expr1 is less than expr2"
elif [expr2 -gt $expr2]; then
    echo "expr1 is greater than expr2"
else if[expr1 -eq $expr2]; then
    echo "expr1 is equal to expr2"
else
    echo "Invalid"
fi

沒有留言:

發佈留言