BASH SHELL

1. **Common execute -**pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls
2. **Process list - creates subshell  -**(pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls ; echo $BASH\_SUBSHELL) or ( pwd ; (echo $BASH\_SUBSHELL
3. **External command: - they need to fork**

* **​**which ps -/bin/ps
* type -a ps

* ls -l /bin/ps

    **4.Bulit-in command - they not need to for**

* type cd

* type -a echo

* which echo

* type -a pwd

**5**.**Global variables** -are visible from the shell session and from any spawned child subshell.

* printenv
* echo $HOME
* export my\_variable= 'my variable'
* unset my\_variable

6**.Setting PATH env variable -**PATH=$PATH:/home/christine/Scripts

7. **Login shell** --when you log in to the linux, bash shell starts as a login shell - - /etc/profile ,.bash\_profile,.bashrc,.bash\_login

8.**Interactive shell process** -start a bash shell without logging into a system( if you just type bash at CLI prompt) , it doesnt process /etc/profile, checks only for .bashrc

9. **Non-interactive shell process** -This is where the system can start to execute a shell script

10. **INPUT REDIRECTION**-

 -normal version command < inputfile for eq. wc < test6.txt

 -inline input redirection

command << marker
     eq. wc << EOF
     test string 1
     test string 2
     test string 3
     EOF
11. **EXPR command** -  expr 1 + 5

**Command operators**

 a) ARG1 | ARG2 - Return ARG1 if neither argument is null or zero, otherwise returns ARG2
 b) ARG1 & ARG2 - Return ARG1 if neither argiment is null or zero, otherwise returns 0
 c) ARG1 < ARG2 - Return 1 if ARG1 is less than ARG2, otherwise return 0
 d) ARG1 <= ARG2 - Return 1 if ARG1 is less than or equal to ARG2, otherwise returns 0
 e) ARG1 = ARG2 - Return 1 if ARG1 is equal to ARG2, otherwise returns 0
 f) ARG1 != ARG2 - Return 1 if ARG1 is not equal to ARG2, otherwise returns 0
12. **EXIT status codes**

     a) 0 - sucessful
     b) 1 - general unknown error
     c) 2 - misuse of shell command
     d) 126 - The command can't execute
     e) 127- Command not found
     f)  128 - Invalid exit argument
     g) 130 - Command terminated with Ctrl +c
     h) 255 - Exit status of out range
13. **IF statement**  - if exit status of the command is zero(command is completed sucesfully) the command under then section are executed.

```
if command1

then

   commands

elif command2

then

    more commands

fi

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

if [ condition ]; then

    commands

fi

if [ -e $tmpFile ]; then
           rm -f $tmpFile

fi

if [ ! -e "$tmpfile" ]; then
                  touch "$tmpfile"

if [ -f "$pid" ]; then
            echo "Deleting uncessesary pid of tftpd server" >> ${logFile}
            rm -f $pid
else
            echo "File not found"
fi

if [ $rc = "ok" ]; then
                 echo Network is OK
else
                 echo Network problem
fi

```

14.**Test comparisions**

**1)Numeric comparisons**
   n1 -eq n2  **check if n1 is equal to n2**
   n1 -ge n2  **check if n1 is greater than or equal to n2**
   n1 -gt n2   **check if n1 is greater than n2**
   n1 -le n2   **check if n1 is less than or equal to n2**
   n1 -lt n2    **check if n1 is less than n2**
   n1 -ne n2  **check if n1 is not equal to n2**

**Bash shell can handle only integers.**

**2)String comparisions -- string order also - alfabetically or ascii**

   str1 == str2  **Checks if str1 is the same as string str2**
   str1 != str2   **Checks if str1 is not the same as str2**
   str1 < str2    **Checks if str1 is less than str2**
   str1 > str2    **Checks if str1 is greater than str2**
   -n  str1       **Checks if str1 has a lenght greather than zero**
   -z  str1         **Checks if str1 has a lenght of zero**

**3)File comparisions**

  -d file       **Checks if file exists and is a directory**
  -e file       **Checks if file exists**
  -f file        **Checks if file exists and is a file**
  -r file     **Checks if file exists and is readable**
  -s file       **Checks if file exists and is not EMPTY**
  -w file       **Checks if file exists and is writable**
  -x file       **Checks if file exists and is executable**
  -O file       **Checks if file exists and is owned by the current user**
  -G file       **Checks if file exists abd the default group is the same as the current user**
  file1 -nt file2    **Checks if file1 is NEWER than file2**
  file1 -ot file2    **Checks if file1 is OLDER than file2**

**4) compound testing**

[ condition1 ] && [ condition2 ] - AND - **both condition must be met**
[ condition1 ] || [ condition2 ] - OR  - **If one of condition is true, then "then" secton is executed.**

**15)CASE COMMAND - checks multiple values of a single variable in a list-oriented**

```
case variable in

pattern1 | pattern2) commands1;;

paterrn3) commands;;

*) default commands;;

esac

case $USER in

rich | barbara)

    echo "WELCOME, $USER"

    echo "PLEASE ENJOY your visit";;

testing)

     echo " Special testing account ";;

jessica)

     echo "Do not forget to log off when you're done";;

*)

     echo "Sorry, you are not allowed here";;

esac

```

**16) FOR LOOP - Within the commands the $var variable contains the current list item value for**

**the iteration**

```
for var in list

do

   commands

done

for state in $(cat $file) ## REMEMBER ABOUT IFS!

do

   echo "Visit beautiful $state"

done

for HOST in $dstIP; do

        ssh fgtuser@$HOST "sudo $scriptPath"

done

for i in {1..10}; do

        if ping -c1 -w1  $1  >/dev/null 2>&1; then

                rc=ok

                continue

        fi

        rc=error

done

for file in /home/rich/test/.b* /home/rich/badtest

do

   if [ -d "$file" ] # $file in "" because the filenames can contain spaces

   then

       echo "$file is a directory"

   elif [ -f "$file" ]

       echo "$file is a file"

   else

       "$file doesn't exist"

done > output.txt

for state in "North Dakota" Connecticut Illnois Alabama Tennessee

do

   echo "$state is the next place to go"

done | sort

for (( i=1; i <= 10; i++ ))

do

   echo "The next number is $i"

done

for (( a = 1; a <= 3; a++ ))

do

    echo "Staring loop $a:"

    for (( b = 1; b <= 3; b++ ))

    do

        echo " Inside loop :$b "

    done

done
factorial=1

for (( number = 1; number <= $1; number ++ ))

do

  factorial=$[ $factorial * $number ]

```

18 ) **IFS-internal field separator , definies a list of character the bash shell usesas field separators.**

**By default:**
-a space
-a tab
-a newline
If the bash shell sees any of these characters in the data, it assumes that you're
stating a new data in the list. When working that data can contain spaces
this can be annoying. To solve problem -> temporarily change the IFS env value

More than one character : IFS=$'\n':;" - new line , a colon, a semicolon and
double quotation mark.
IFS.OLD=$IFS
IFS=$'\n'

```
for entry in $(cat /etc/passwd )

do

    echo "Values in $entry-"

    IFS=:

    for value in $entry -"

      do

          echo " $value"

       done

   done

```

**19) Controlling loop**

**-break n** - escape a loop in progress

**-continue n** - prematurely stop processing commands inside of a loop but not terminate loop completely.

```
BREAK

for var1 in {1..10}

do

  if [ $var1 -eq 5 ]

  then

     break

  fi

  echo "Iteration number: $var1 "

done

```

```
CONTINUE

for (( var1 = 1; var1 < 15; var1++ ))

do

    if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]

    then

      continue ## 1,2,3,4,5 10 11 12 13 14

    fi

    echo "Iteration number : $var1 "

done

```

20)**WHILE**- define a command to test and then loop through a set of commands for as

             long as definied test command returns a zero exit status.

             When the test command returns a non zero exit status, the while stops executing

             the set of commands

             KEY to the WHILE is that the exit status of test command specified must change

             based on the commands run during the loop

```
while test command

do

   others commands

done

var1=10

while [ $var1 -gt 0 ]

do

     echo $var1

     var1=$[ $var1 - 1 ]

done

var1=10

while echo $var1

      [ $var1 -ge 0 ]

do

    echo "This is inside the loop"

    var1=$[ $var1 - 1 ]

done

```

**21) UNTIL LOOP**-Requires that you specyfiy a test command that normally produces a non-zero

exit status. As long as the exit status of the command is non-zero, the bash shell

executes the command listed in the loop. When the test command returtns a

zero exit status, the loop stops

```
until test commands

do

     other commands

done

var1=100

until [ $var1 -eq 0 ]

do

      echo $var1

      var1=$ [ $var1 - 25 ]

done

var1=100

until echo $var1

      [ $var1 -eq 0]

do

    echo Inside the loop: $var1

    var1=$[ $var1 - 25 ]

done

until [ $counter -lt 11]; do iptables -D networksOUTPUT $count; done;

```

**22) PASSING PARAMETERS**

* $0- script name
* $1- first parameter
* $2- second parameter

up to $9.
**$#  - contains the number of command line parameters included when the script was run.**

```
if [ $# -ne 2 ]

then

   echo

   echo Usage: test9.sh a b

   echo

else

   total=$[ $1 + $2 ]

   echo

   echo The total is $total

fi

```

**${!#} - last command line parameter variable**

```
params=$#

echo

echo The last parameter is $params

echo The last parameter is ${!#}

echo

```

**$\* - take all the parameters on the command line as a single word**

**$@-take all the parameters supplied on the command line as separate words in the same string.**

```
count=1

for param in "$@"

do

   echo "\$@ Parameter #$count = $param"

   count=$[ $count + 1 ]

done

```

**23) SHIFT - shifts the command parameters, variable one position to the left by default.**

```
echo

count=1

while [ -n "$1" ]

do

    echo "Parameter #$count = $1"

    count=$[ $count + 1 ]

    shift

done

echo

echo "the orginal parameters: $*"

shift 2

echo "Here's the new first parameter: $1"

./test 1 2 3 4 5 , new parameter : 3

```

**24) OPTIONS**

**a)simple option**

```
echo

while [ -n "$1 ]

  do

     case "$1" in

     -a) echo "Found the -a option";;

     -b) echo "Found the -b option";;

     -c) echo "Found the -c option";;

      *) echo "$1 is not an option";;

  esac

  shift

done

```

This method works no materr of what order

* + - * + - * + - * + - * + - *

**b)separating options from parameters**

```
echo

while [ -n "$1" ]

do

   case "$1" in

      -a) echo "Found the -a option" ;;

      -b) echo "Found the -b option" ;;

      -c) echo "Found the -c option" ;;

      --) shift

          break ;;

       *) echo "$1 is not a option" ;;

   esac

   shift

done

#

count=1

for params in "$@"

do

   echo "Parameter #$count: $param"

   count=$[ $count + 1 ]

done

```

-- this indicate the end of the options and starts parameter

./$0 -c -a -b -- test1 test2 test3

**c) options with values**

```
#!/bin/bash

echo

while [ -n "$1" ]

do

   case "$1" in

      -a) echo "Found the -a option" ;;

      -b) params="$2"

          echo "Found the -b option, with parameter value $params"

          shift ;;

      -c) echo "Found the -c option" ;;

      --) shift

          break ;;

       *) echo "$1 is not a option" ;;

   esac

   shift

done

#

count=1

for params in "$@"

do

   echo "Parameter #$count: $param"

   count=$[ $count + 1 ]

done

```

./$0 -a -b test1 -d

IT's not working with combining options for eg -ac

**d) getopt**

**getopt optstring parameters**

List all command line option, place a colon : after each option that requires a parameter value.

getopt ab:cd -a -b test1 -cd test2

-q ignore error messages

set -- $(getopt -q ab:cd "$@")

```
echo

while [ -n "$1" ]

do

   case "$1" in

      -a) echo "Found the -a option" ;;

      -b) params="$2"

          echo "Found the -b option, with parameter value $params"

          shift ;;

      -c) echo "Found the -c option" ;;

      --) shift

          break ;;

       *) echo "$1 is not a option" ;;

   esac

   shift

done

#

count=1

for params in "$@"

do

   echo "Parameter #$count: $param"

   count=$[ $count + 1 ]

done

./$0 -ac and $0 -a -b test1 -cd test2 test3 test4

```

Problems with parameters that contains spaces and quotation mark

**e)getopts**

```
echo

while getopts :ab:c opt

do

   case "$opt" in

       a) echo "Found the -a option" ;;

       b) echo "Found the -b option with value $OPTARG" ;;

       c) echo "Found the -c option" ;;

       *) echo "Unknown option $opt" ;;

   esac

done

   shift $[ $OPTIND -1 ]

#

count=1

for params in "$@"

do

   echo "Parameter #$count: $param"

   count=$[ $count + 1 ]

done

./$0 -a -b test1 -d test2 test3 test4

```

    OPTARG env - contains the value used if an option require a parameter value

  OPTIND env - contain the value of the current location within parameter list

  :ab - to suppress error messages

pros

- spaces in parameters

- option and letter and the parameter value together ./test19.sh -abtest1

-undefinied option sends question mark

**25) GET USER INPUT**

**a)** echo -n "Enter your name: "
read name
echo "Hello $name, welcome to my program"

**b)** read -p "Please enter your age.." age - -p allows us to specify a prompt directly in the read command line

**c)** read -p
 echo
 echo Hello $REPLY - contains all the data entered in the input

**d)** if read -t 5 -p "Please enter your name " name
 then
     echo "Hello $name, welcome to my script"
 else
     echo
     echo "Sorry, too slow"
 fi
     timer 5 seconds

**e)** read -n1 -p "Do you want to continue [Y/N]? " answer
 case $answer in
 Y | y) echo
        echo "fine, continue on..";;
 N | n) echo
        echo OK, goodbye
        exit;;
 esac
 echo "This is the end of the script

 Counting the input

**f)** without display on monitor
 read 0s

**e)**count=1
cat test | while read line
do
   echo "Line $count: $line"
   count=$[ $count + 1]
done
echo "Finished processing the file"

**26) PRESENTING DATA**

**file descriptors:**
0 STDIN Standard Input
1 STOUT Standard Output
2 STERR Standard Error

**STDIN**
-keyboard
cat < testfile

**STDOUT**-standard output for the shell
ls -l > test2
who >> test2

**STDERR**
ls -al badfile 2> test4- redirect only error
ls -al test test2 test3 badtest 2> test6 1> test7 -stdout to test7 stderr to test6
ls -al test test2 test3 badtest &> test7 - STDERR and STDOU to the same file

**REDIRETING OUTPUT IN SCRIPT**
- temporarily redirecting each line

echo "This is an error messsage" >&2 - redirect to a file descriptior STERR
for e.g
echo "This is an error" >&2
echo "This is a normal output"
Result : You don't notice any diferrence
or ./$0 2> test3 - redirect error message to other file

**-permament redirection**
exec 1> testout - all STDOUT  of script goes to file testout
exec 2> testerr -all STERR to test script
touch $LOGFILE
exec 6>&1 # Link file descriptor #6 with stdout.
1. Saves stdout.

exec > $LOGFILE # stdout replaced with file $LOGFILE
touch $LOGERR
exec 7>&2 # Link file descriptor #7 with stderr.
1. Saves stderr.

exec 2> $LOGERR # stderr replaced with file $LOGERR.

**to close the descriptors**
exec1>&6
exec 2>&7

exec 6>&-
exec 7>&-

**-listing open file descriptors - nine file descriptor**s
/usr/sbin/lsof -a - p $$ -d 0,1,2
-a = for boolean AND , $$ - current pid
-d descriptors

**28) TEMPORARY FILES**

mktemp testing.XXXXXX - six X

tempfile=$(mktemp test19.XXXXXX)
exec > $tempfile

mktemp -t test.XXXXXX - temporary file in /tmp
mktemp -d dir.XXXXXX - temporary directory

tempdir=$(mktemp -d dir.XXXXXX)
cd $tempdir
tempfile1=$(mktemp temp.XXXXXX)
tempfile2=$(mktemp temp.XXXXXX)

**29) LOGGING MESSAGES**

tee - sends data from STDIN to two destinations at the same time
date | tee - tee command overwrites the output file on each use
date | tee -a testfile  - a append,

**30)SIGNALS**

1-  SIGHUP  -HANGS UP the process
2-  SIGINT  -INTERUPTS the process - CTRT +C
3-  SIGQUIT -STOPS the process
9-  SIGKILL -Unconditionally terminates the process
15- SIGTERM -Terminates the process if possible
17- SIGSTOP -Unconditionally stops but doesn't terminate the process
18- SIGTSTP -Stops or pauses the process, but doesn't terminate - CTRL +Z
19- SIGCONT -Cibtubyes a stopped process

By default the bash shell ignores -SIGQUIT(3) and SIGTERM (15)

Not ignore - SIGHUP(1) and SIGINT(2)

33) **Trapping signals**

trap commands signal
Allows to specify which Linux signals your shell scripts watch for and intercept from shell

```
#!/bin/bash

#Testing trap signals

trap "echo 'Sorry I have trapped CTRL-C'" SIGINT

#

#

echo This is a test script

#

count=1

while [ $count -le 10 ]

do

    echo "Loop #$count"

    sleep 1

    count=$[ $count +1 ]

done

trap "echo goodbye" EXIT - it also works when you prematurelt exit the script

```

Last day of every month CRON

00 12 \* \* \* if [ `date +%d -d tommorow` = 01 ] ; then ; command -
Last day of every month - if tommorow date is 01

**34 ) STANDARD BASH VARIABLES**

- BASH\_ENV - name of a file which is parsed before executing the file

- BASHOPTS - list of enabled shell opts  = shopt | grep -w on

       -s to set , -u- unset

       Options

         - checkhash - this will check to see if a hashed PATH entry still exists before attempting to execute the file

         - checkwinsize - updates the LINES and COLUMNS variables after every command

         - cmdlist -reduces multiline commands

         - hostcomplete -

         - login\_shell - this is set if the current shell is a login shell

- SHELLOPTS

      -echo $SHELLOPTS

      -e / -o errexit - exit  if any command returns a non zero exit status code

      -f / -o noglob - disables pathname expansion

      -m / -o monitor -if set, when a background command completes, you will get a line the next time bash

      displays a new prompt

      -pipefail - (default off )detects the error from any of the commands in the pipeline

      -o vi

      -x - this displays every command before executes it