The Part#3 includes:
- Variable scope
- let command
- case statements
- eval command
- wildcards
- Logger
- Reading a file line by line
- expr command
- loop control statements - Break and Continue
- Debugging
variable scope:
Global:
- By default, variables are global.
- define variables before use it
- If you define a global variable in a function, it will be only be available after the function is called.
Local:
- Can only be accessed within a function using a local keyword, example: local LOCAL_VARIABLE=1
let command:
- The let command is an arithmetic operator. It is almost same as (( )). Only difference is that, let is an arithmetic command while (( )) is a compound command.
- It is a built-in command which instructs shell to perform an evaluation of arithmetic expressions. No spaces should be used around the arithmetic operand with let command.
let y=y+1
echo $y
1
let y="34 +45"
echo $y
79
case statements:
A case construct helps us to simplify nested if statement. You can match several variables against one variable. Each case is an expression matching a certain pattern.
Syntax:
case $var in
pattern_1)
Commands
;;
pattern_N)
Commands
;;
esac
Example:
cat > case.sh
#!/usr/bin/bash
echo "Enter the name of the State"
read state
case $state in
"Uttar Pradesh")
echo "Capital id Lucknow"
;;
"Bihar")
echo " Capital id Patna"
;;
*)
echo " You discovered an unknown state"
;;
esac
chmod +x case.sh
./case.sh
Enter the name of the State
Bihar
Capital id Patna
./case.sh
Enter the name of the State
bihar
You discovered an unknown state
eval command:
The eval command is a built-in command. It takes a string as its argument and evaluate it, then run the command stored in the argument. It allows using the value of a variable as a variable.
eval echo \${$User}
cat > eval.sh
#!/usr/bin/bash
hello=Mr.x
user=hello
echo \${$user}
eval echo "\${$user}"
chmod +x eval.sh
./eval.sh
$[hello}
Mr.x
But command "eval echo \${$User}" runs the parameter passed to eval. After expansion, remaining parameters are echo and ${Hello}. Hence eval command runs the command echo ${Hello}. And so the output is Mr. X
Wild cards:
- A character or string used for pattern matching.
- wildcards can be used with most of the commands like cp, ls, rm etc.
? : Matches exactly one character
Character classes[]: Matches any of the characters included between the brackets.matches exactly one character.
Example:
[aeiou]
ca[nt]* : can, cat, candy, catter etc.
Character classes [!]: Matches any of the characters not included between the brackets. matches exactly once character.
Example:
[!aeiou] : Devdas, criccket.
Ranges: use two chars separated by a hypen to create a range in a character class.
[a-g]* : matches all files starting with a,b,c,d,e,f,g
[1-5]*: matches all files started with 1,2,3,4,5
Named character class:
[[:alpha:]]
[[:alnum:]]
[[:digit:]]
[[:lower:]]
[[:upper:]]
[[:space::]]
escape character: "\" is called escape character. use it to match a wildcard character.
Example:
*\? : match all files that end with a question mark.
Example:
ls -l a*
-rwxr-xr-x 1 oracle dba 22 Aug 11 03:20 a.sh
ls c[aeiou]*
case.sh config.sh
ls c[!aeiou]*
c.sh
ls [a-d]*
a.sh b.sh c.sh case.sh config.sh
ls [[:digit:]]*
20200819mycat.jpg
ls *.txt
test.txt
ls ?est.txt
test.txt
copying all the html files from current directory to /a directory.
#!/usr/bin/bash
for FILE in *.html
do
echo "copying $FILE"
cp $FILE /a
done
Logging:
Syslog:
- The syslog standards uses facilities and severities to categorize messages.
- Facilities: kern,mail,user,daemon,auth,local0
- Severities: alert, emerg,crit,err,warning,notice,info debug
- Log files locations are configureables
- /var/log/messages
- /var/log/syslog
logger "Message"
logger -p local0.info "Message"
logger -t myscript -p local0.info "Message"
logger -i -t myscript -p local0.info "Message"
Reading a file line by line:
#!/usr/bin/bash
LINE_NUM=1
while read LINE
do
echo "$LINE_NUM : $LINE"
((LINE_NUM++))
done < /test/test.txt
expr command:
- The expr command in Unix evaluates a given expression and displays its corresponding output. It is used for: Basic operations like addition, subtraction, multiplication, division, and modulus on integers.
- Evaluating regular expressions, string operations like substring, length of strings etc.
Syntax:
$expr expression
Performing operations on variables inside a shell script
Example: Adding two numbers in a script
echo "Enter two numbers"
read x
read y
sum=`expr $x + $y`
echo "Sum = $sum"
Note: expr is an external program used by Bourne shell. It uses expr external program with the help of backtick. The backtick(`) is actually called command substitution.
Comparing two expressions
Example:
x=10
y=20
# matching numbers with '='
res=`expr $x = $y`
echo $res
# displays 1 when arg1 is less than arg2
res=`expr $x \< $y`
echo $res
# display 1 when arg1 is not equal to arg2
res=`expr $x \!= $y`
echo $res
For String operations
Example: Finding length of a string
x=geeks
len=`expr length $x`
echo $len
Example: Finding substring of a string
x=geeks
sub=`expr substr $x 2 3`
#extract 3 characters starting from index 2
echo $sub
Break Statement:
The break statement is used to terminate the execution of the entire loop, after completing the execution of all of the lines of code up to the break statement. It then steps down to the code following the end of the loop.
Syntax:
The following break statement is used to come out of a loop −
break
The break command can also be used to exit from a nested loop using this format −
break n
Here n specifies the nth enclosing loop to the exit from.
Example 1:
Here is a simple example which shows that loop terminates as soon as a becomes 5 −
#!/usr/bin/bash
a=0
while [ $a -lt 10 ]
do
echo "$a"
if [ $a -eq 5 ]
then
break
fi
a=`expr $a + 1`
done
Upon execution, you will receive the following result −
0
1
2
3
4
5
Example 2 of nested for loop. This script breaks out of both loops if var1 equals 2 and var2 equals 0 −
#!/usr/bin/sh
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
Upon execution, you will receive the following result. In the inner loop, you have a break command with the argument 2. This indicates that if a condition is met you should break out of outer loop and ultimately from the inner loop as well.
1 0
1 5
The continue statement:
The continue statement is similar to the break command, except that it causes the current iteration of the loop to exit, rather than the entire loop.
This statement is useful when an error has occurred but you want to try to execute the next iteration of the loop.
Syntax
continue
Like with the break statement, an integer argument can be given to the continue command to skip commands from nested loops.
continue n
Here n specifies the nth enclosing loop to continue from.
Example 1:
The following loop makes use of the continue statement which returns from the continue statement and starts processing the next statement −
#!/bin/sh
NUMS="1 2 3 4 5 6 7"
for NUM in $NUMS
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "Number is an even number!!"
continue
fi
echo "Found odd number"
done
Upon execution, you will receive the following result −
Found odd number
Number is an even number!!
Found odd number
Number is an even number!!
Found odd number
Number is an even number!!
Found odd number
Debugging:
Debugging is required to fix bugs or errors and to determine the root of unexpected behavior.
Technique 1:
cat >debug.sh
#!/usr/bin/bash -x
VAR_TEST="test"
echo "$VAR_TEST"
chmod +x debug.sh
./debug.sh
Output:
+ VAR_TEST=test
+ echo test
test
Technique 2:
#!/usr/bin/bash
VAR_TEST="test"
set -x
echo $VAR_TEST
set +x
hostname
output:
+echo test
linuxTestServ
-e option:
- Exit on error
- can be used with other options
- #!/usr/bin/bash -ex
- #!/usr/bin/bash -xe
- #!/usr/bin/bash -e -x
- #!/usr/bin/bash -x -e
Example 1:
#!/usr/bin/bash -e
FILE_NAME="/invalid"
ls $FILE_NAME
echo $FILE_NAME
Output:
ls: 0653-341 The file /invalid does not exist.
/invalid
Example 2:
#!/usr/bin/bash -ex
FILE_NAME="/invalid"
ls $FILE_NAME
echo $FILE_NAME
Output:
+ FILE_NAME=/invalid
+ ls /invalid
ls: 0653-341 The file /invalid does not exist.
-v option: Prints shell input lines as they are read.
#!/usr/bin/bash -v
VAR_TEST="test"
echo "$VAR_TEST"
Output:
#!/usr/bin/bash -v
VAR_TEST="test"
echo "$VAR_TEST"
test
#!/usr/bin/bash -vx
VAR_TEST="test"
echo "$VAR_TEST"
Output:
#!/usr/bin/bash -vx
VAR_TEST="test"
+ VAR_TEST="test"
echo "$VAR_TEST"
+ echo test
test
PS4:
- Controls what is displayed before a line when using teh "-x" option.
- the default value is "+"
- Bash variables BASH_SOURCE, LINENO etc.
Example:
cat > ps4.sh
#!/usr/bin/bash -x
PS4='+ $BASH_SOURCE : $LINENO : '
TEST_VAR="test"
echo "$TEST_VAR"
chmod +x ps4.sh
./ps4.sh
+ PS4='+ $BASH_SOURCE " $LINENO " '
+ ./ps4.sh : 3 : TEST_VAR=test
+ ./ps4.sh : 4 : echo test
test
#!/usr/bin/bash -x
PS4='+ $BASH_SOURCE : $LINENO : $FUNCNAME[0]()'
debug(){
echo "Executing: $@"
$@
}
debug ls
+ PS4='+ $BASH_SOURCE : $LINENO : $FUNCNAME[0]()'
+ ./ps41.sh : 7 : [0]()debug ls
+ ./ps41.sh : 4 : debug[0]()echo 'Executing: ls'
Executing: ls
+ ./ps41.sh : 5 : debug[0]()ls
20200819mycat.jpg
DOS VS Linux file types:
A file can contain CRLF/Carriage return, Line feed. So when we are moving file from DOS system to Linux, we should use " dos2unix script.sh " command to make it compatible with BASH executable.
To continue, go to the next page, bash-scripting-and-shell-programming-part4.
No comments:
Post a Comment