-> ls :

    List all the file or folder present in the current directory.

        Option:

        * -l :  List all the file and folder with permission, owner,
                and group details in form of vertically alinged list.
        
        * -a :  Display hidden (.)dotfile as well.

-> pwd :

    Print the current directory, present on the terminal.

-> date :

    Print the current date and time.

-> chmod :

    Used to change the permission of file or folder

        Symbol Meaning :

        * a : For all (including owner, group and others)
        * u : For owner
        * g : For group
        * o : For others
        * r : read permission ( number 4 )
        * w : write permission ( number 2 )
        * x : execute permission ( number 1 )

        Option :

        * a+x : Add execute permission for all.
        * a-x : Remove execute permission for all.
        * 755 : rwx - user , r-x - group, r-x - others

    How to use?

        chmod a+x "file/folder name"
        chmod 755 "file/folder name"

-> echo :

    To Print argument on the terminal

        Option:

        * -n : Not to add newline.
        * ".." : String to print
        * $PATH : variable ( environment variable, etc. )

-> $PATH environment variable :

    Store the paths which help in invoking executable, script, etc,
    without specifying whole path, where its present.

    How to add path to $PATH?

    export PATH=$PATH:$(pwd)
                        or full path to intended directory.

-> SHABANG (#!/bin/bash)

    Tells to use this interpreter to run the script.
    Same as /bin/bash ./script

-> Variables :

    To stores data and can be changed.

    1. Explicit Defination :
        VAR=value
        COUNT=5
        PATH=/var/lib

    2. Read command :
        read VAR
        read COUNT
        read PATH

        Option :

        * -p :  to print the parameter before read.

            How to use?

                read -p "Your name: " NAME

        * -s :  to hide the input to be taken. Best use
                for password.

            How to use?
            
                read -sp "Your age: " AGE

    3. Command Substitution :

        To store the output of the command executed to the variable.

        How to use?

            VAR=$(pwd) or VAR=`pwd`


    How to use variables?

        Use $variableName for using variables.


-> For Math Calculation :

    1 . let

        let RESULT=NUMBER+5
        let NUMBER++
        let NUMBER--
        let NUMBER+=5
        let NUMBER-=5

    2. (( ))

        RESULT=$(( NUMBER + 5 ))
    
    3. []

        RESULT=$[ NUMBER + 5 ]
    
    4. expr 

        RESULT=$(expr $NUMBER + 5)
        RESULT=`expr $NUMBER + 5`
        RESULT=`expr 2 + 3`

    5. bc ( used for floating point number )

        RESULT=`echo "$NUMBER * 1.9" | bc`


-> Argument :


    $0 - script name
    $1 - first argument
    $2 - second argument
    $n - nth argument
    "$@" - all argument, expands as "$1" "$2" "$3"
            and so on.
    "$*" - all argument as string, "$1c$2c$3", 
            where c is IFS (Internal field
            separator), which is usally whitespace.
    $# - arguments count

-> Redirecting and piping:

    Redirecting

    * STDIN (0) - Standard input (data provided to program)
    * STDOUT (1) - Standard output (what program prints, defaultly to the terminal)
    * STDERR (2) - Standard error (what error message program prints, defaultly to terminal)

    examples:
    cat file1.txt > output_from_cat.txt
    cat file1.txt 1>output_from_cat.txt
    cat file1.txt 2>error.txt
    cat file1.txt 1>output_from_cat.txt 2>error.txt
    cat file1.txt &> output_from_cat.txt (from both 1 and 2)
    cat file1.txt 1> output_from_cat.txt 2>&1(redirecting error to output)

    cat file1.txt >> output_from_cat.txt(adding output instead of replacing it)

    Piping

    output of preceeding program is input to succeeding
    program.

    Program1 | Program2

    examples:
    cat file.txt | wc -l
    cat file.txt | head -5 | tail -3 | wc -l

-> Exit Status

    echo $?

    $? will give a return value of previous command.
    It's the return value, called EXIT STATUS.
    Successfully exiting give 0 value otherwise
    non-zero value.

    We can exit script using exit command.
    exit command can be used with number 0 - 255.

-> If Statement

    if[ condition ]; then
        ....
    elif[ condition ]; then
        ....
    elif[ condition ]; then
        ....
    else
        ....
    fi

    * AND with if statement ?

    if[ condition ] && [ condition ]; then
        ....
    fi

    * OR wiht if statement ?

    if[ condition ] || [ condition ]; then
        ....
    fi

    * Negate if condition

    if[ !condition ]; then
        ....
    fi

    if![ condition ]; then
        ....
    fi

-> Mathematical comparison:

    * Operands

        $ -eq   equal to
        $ -ne   not equal to
        $ -gt   greater than
        $ -lt   less than
        $ -ge   greater than or equal to
        $ -le   less than or equal to

    Examples:

        if [ $VAR -eq 5 ]; then
        if [ $VAR -gt 7 ]; then
        if [ $VAR -eq 5 ] && [ $COUNT -ne 1 ]; then



-> String Comaparison

    * Comapare two strings
    [ "$STR1" = "$STR2" ]
    [ "$STR1" != "$STR2" ]

    [ "$STR1" = "hello" ]
    [ "$STR1" != "hello" ]

    * Compare two strings - quotation marks?
      Bash can handle it in another way [[ ]]

      [[ $STR1 = $STR2 ]]
      [[ $STR1 != $STR2 ]]

      [[ $STR1 = "hello" ]]
      [[ $STR1  != "hello ]]

      This is not widely used and most scripts
      are using quotation marks with single 
      brackets

    * Test if string is empty

        [ -z "$STR1" ] returns true if STR1 holds
                        an empty string

        [[ -z $STR1 ]] possible, but not widely used
        
        [ -n "$STR1" ] returns true if STR1 holds
                        a non-empty string

        [[ -n $STR1 ]] possible, but not widely used

    * Alphabetically compare two strings

    [[ $STR1 > $STR2 ]]

    [[ $STR1 < $STR2 ]]

    No choice!!!

    * Wildcards

        [[ $STR1 == string-with-wildcards ]]

    * Regular expression

        [[ $STR1 =~ $regex ]]


-> Wildcards (globbing patterns)
|-----------------------------------------------------------------------|
|   Symbol  |   Description     |   Example     |   Example matches     |
|-----------------------------------------------------------------------|
|   ?       |   Single          |   hel?        |   help, hell,         |
|           |   character       |               |   hel1....            |
|-----------------------------------------------------------------------|
|   *       |   Any number of   |   ca*         |   car,ca,carpet,      |
|           |   characters      |               |   carpenter,car112..  |
|           |   (including zero)|               |                       |
|-----------------------------------------------------------------------|
|   []      |   Single character|   file[0-2]   |   file0,file1,file2   |
|           |   from range      |   [hd]ello    |   hello or dello      |
|-----------------------------------------------------------------------|
|   {}      |   Comma seperated |   {*.txt,     |   hello.txt,doc.txt,  |
|           |   terms           |   *.pdf}      |   source.pdf, book.pdf|
|-----------------------------------------------------------------------|
|   [!]     |   Any character   |   file[!1]    |   file2,file3....     |
|           |   listed in       |               |                       |
|           |   brackets        |               |                       |
|-----------------------------------------------------------------------|

    * some useful character classes: (use it within [])

    |-------------------------------------------|
    |   [:upper:]   |   Uppercase character     |
    |   [:lower:]   |   Lowercase character     |
    |   [:alpha:]   |   Alphabetic character    |
    |   [:digit:]   |   Number character        |
    |   [:alnum:]   |   Alphanumric character   |
    |               |   (alpha + digit)         |
    |   [:space:]   |   whitespace character    |
    |               |   (space, tab, newline)   |
    |-------------------------------------------|

* [[ $STRING == pattern_with_wildcards ]]
* [[ $STRING == file[0-9].txt ]]
* [[ $STRING == rich* ]]


-> Regular Expressions

|-----------------------------------------------------------|
|   Symbol  |   Description |   Example |   Example matches |
|-----------------------------------------------------------|
|   .       |   any single  |   bo.k    |   book,bo1k, ...  |
|           |   character   |           |                   |
|-----------------------------------------------------------|
|   *       |   preceeding  |   co*l    |   cl,col,cool, ...|
|           |   item must   |           |                   |
|           |   match zero  |           |                   |
|           |   or more     |           |                   |
|           |   times       |           |                   |
|-----------------------------------------------------------|
|   ^       |   Start of    |   ^hello  |   line starting   |
|           |   the line    |           |   with hello      |
|           |   marker      |           |                   |
|-----------------------------------------------------------|
|   $       |   End of the  |   hello$  |   line ending     |
|           |   line marker |           |   with hello      |
|-----------------------------------------------------------|
|   []      |   Any one of  |   coo[kl] |   cook or cool    |
|           |   of character|           |                   |
|           |  enclosed in[]|           |                   |
|-----------------------------------------------------------|
|   [-]     |  Any character|  file[1-3]|  file1,file2,file3|
|           |   within the  |           |                   |
|           |   range       |           |                   |
|-----------------------------------------------------------|
|   [^]     |  Any character|   file[^0 |   file8,file9     |
|           |   except those|   1234567]|                   |
|           |   enclosed in |           |                   |
|           |   brackets    |           |                   |
|-----------------------------------------------------------|
|   ?       |   preceeding  |   colou?r |   color,colour    |
|           | item must     |           |   NOT colouur     |
|           | one or zero   |           |                   |
|           |   times       |           |                   |
|-----------------------------------------------------------|
|   +       | preceeding    |   file1+  |   file1,file11,   |
|           | item must     |           |   file111         |
|           | match one or  |           |   NOT file        |
|           |   more times  |           |                   |
|-----------------------------------------------------------|
|   {n}     | preceeding    |   [0-9]{3}|   Any three digit:|
|           | item must     |           |   097,256,787,... |
|           | match n times |           |                   |
|-----------------------------------------------------------|
|   {n,}    | Minimum number|  [0-9]{3,}|   Any three digit |
|           | of times the  |           |   111,097,256,787.|
|           | preceeding    |           |                   |
|           | item should   |           |                   |
|           | match         |           |                   |
|-----------------------------------------------------------|
|   {n,m}   | Minimum and   | [0-9]{1,3}|   1,158,26, ...   |
|           | maximum number|           |   NOT 1258,1111,..|
|           | of times the  |           |                   |
|           | preceeding    |           |                   |
|           | item should   |           |                   |
|           | match         |           |                   |
|-----------------------------------------------------------|
|   \       | Escape        |   hell\.o |   hell.o          |
|           | character -   |           |   NOT:helllo,     |
|           | escape any of |           |   hell1o...       |
|           | the special   |           |   (Usefule with   |
|           | character,    |           |    grep)          |
|           | ignore the    |           |                   |
|           | meaning of    |           |                   |
|           | them          |           |                   |
|-----------------------------------------------------------|

-> Regex in Bash

    * [[ $STRING =~ $REGEX ]]
    * REGEX="http://.*\.jpg"
    * ${BASH_REMATCH[0]} -> part of the STRING which match
                            REGEX (e.g. http://images.jpg)
    * ${BASH_REMATCH[1]} -> part of the REGEX which is
                            enclosed in first parentheses,
                            e.g.
                            REGEX="http://(.*)\.jpg" -> which
                            would represents as "images"


-> Filesystem Related Tests

|-----------------------------------------------------------------------|
|   File Test operators |   Description, what is returned               |
|-----------------------------------------------------------------------|
|   [ -e $VAR ]         |   True if variable hold existing file (file   |
|                       |   or directory)                               |
|-----------------------------------------------------------------------|
|   [ -f $VAR ]         |   True if variable holds an existing regular  |
|                       |   file                                        |
|-----------------------------------------------------------------------|
|   [ -d $VAR ]         |   True if variable holds an existing directory|
|-----------------------------------------------------------------------|
|   [ -x $VAR ]         |   True if variable is an executable file      |
|-----------------------------------------------------------------------|
|   [ -L $VAR ]         |   True if variable holds th path of a symlink |
|-----------------------------------------------------------------------|
|   [ -r $VAR ]         |   True if variable holds file that is readable|
|-----------------------------------------------------------------------|
|   [ -w $VAR ]         |   True if variable holds file that is writable|
|-----------------------------------------------------------------------|

        * Example:
            if [ -f $FILE ]; then
                echo File exists
            else
                echo File does not exists
            fi

-> && and ||

    *examples
        [ $? -eq 0 ] && echo command OK || echo something went wrong
            |-----------------|                      |
        if true             execute this             |
                            if NOT true              |
                                |--------------------|


-> For loops

    for arg in [list]
    do
        command(s)..
    done

    * Example 
        for PLANET in "Mercury Venus Earth"
        do
            echo $PLANET
        done

        for file in *.txt
        do
            $file
        done

-> For loops - C style for loops

    for ((i=1; i <= 10 ; i++))
    do
        echo $i
    done

-> While loop

    while [ condition ]
    do
        command(s)
    done

-> C-style While loop

    while (( condition ))
    do
        command(s)
    done

    * Example
        A=1
        LIMIT=10
        while (( A < LIMIT )) //no $ here
        do
            touch $A
            let A++
        done

-> Reading Files with While loop

    while read line
    do
        command(s)..
    done < "$FILENAME"

    cat "$FILENAME" |
    while read line
    do
        echo $line
    done

-> Case:

    case "$VAR" in

        "$condition1")
            command(s)...
        ;;
        "$condition2")
            command(s)...
        ;;
        *)
        command(s)..
        ;;
    esac

    *Example:

    case "$(whoami)" in

     "root")
            echo you are root
            ;;
     "richard"|"susan")
            echo you are user
            ;;
     *)
            echo I don't know you
            ;;
    esac

-> shift 
    It's a command to throw away the parameter count
    that is given to the script.


-> getopts:

    * easy way how to parse short positional parameters (-f)
    * doesn't support long positional parameters ( --help )
    
    * getopts optstring name

    -> For examples:

        #!/bin/bash

        while getopts a:b:cd param; do
         case $param in                                                     OPTIND is initialized to 1
            a)  echo ""                                                     each time the shell or a
                echo "parameter 'a' with argument: $OPTARG"                 shell script is invoked.
                ;;
            b)  echo "parameter 'b' with argument: $OPTARG"                 getopts places index of the
                ;;                                                          next argument to be
            c)  echo "parameter 'c' selected (no colon, no argument)"       processed into the variable
                ;;                                                          OPTIND
            d)  echo "parameter 'd' selected (no colon, no argument)"
                ;;
         esac
        done


-> getopt:

    * parse command options (enhanced)

    opts=`getopt -o a::b:cde --long file::,name::,help -- "$@"`
    eval set -- "$opts"

    #!/bin/bash

    echo "All arguments: $@"
    opts=`getopt -o a::b:cde --long file::,name:,help -- "$@"`
    eval set -- "$opts"
    echo "All arguments after getopt: $@"

-> Arrays:

    * Declaration
        * ARRAY=(value1 value2 .. valueN)
        * ARRAY=(one,two,three)

    * Calling
        * ${ARRAY[0]}   #one
        * ${ARRAY[1]}   #two
        * ${ARRAY[2]}   #three

    
    * ARRAY=(one,two,three)

        ${ARRAY[0]}     #one
        ${ARRAY[1]}     #two
        ${ARRAY[2]}     #three
        ${ARRAY[@]}     #all items in Arrays
        ${ARRAY[*]}     #all items in array, delimited by first character of IFS
        ${!ARRAY[@]}    #all indexes in the array ( @/* )
        ${#ARRAY[@]}    #number of items in the array ( @/* )
        ${#ARRAY[0]}    #length of item zero

-> Functions

    * function_name(){
        <commands>
      }

    * function function_name{
        <commands>
      }

    * Example
        | function hello{
        |     echo hello
        | }
        |
        | echo "output from function hello: "
        | hello



        | function hello{
        |     echo hello $1
        |     return 11
        | }
        |
        | echo "output from function hello: "
        | hello richard
        | echo "return value from function hello is: $?"



        | function hello {                      function hello{
        |   name=$1                                 local name=$1
        |   echo "hello $name"                      echo "hello $name"
        | }                                     }
        |
        | echo "enter your name:"               echo "enter your name:"
        | read name     #richard                read name       #richard
        | hello Peter   #hello Peter            hello Peter     #hello Peter
        | echo $name    #Peter                  echo $name      #richard


-> Comments:

    * Single line:
        use: #

    * Multi-line:
        use: : << cmt
             This is
             multiline Comments
             in bash
             cmt

-> String in double quotes:

    In double quotes the variable value is replaced
    but the special character like * (wildcard)
    character is not replaced.
    
    Special character is replaced when used without
    double quotes and without double quotes use '\'
    before it to supress the behaviour of special
    characters.

-> source keyword:

    source keyword is used to run the shell script
    in the same bash shell.

    Since, running a shell scripts run the script
    in seperate bash shell by default, running it
    with source keyword run the script in same bash
    shell.

    Syntax:
    source ./<script-name>

-> := operator:

    This operator only used to initialize uninitialized
    variable with a value.

    Syntax:

    hh = 4;
    hh := 5;
    echo hh

    Output:
    4