Saturday, November 30, 2019

[Unix / Linux Shell Tutorial - Lession8] Loops

  1. #!/bin/bash
  2. # Basic while loop
  3. counter=1
  4. while [ $counter -le 10 ]
  5. do
  6. echo $counter
  7. ((counter++))
  8. done
  9. echo All done



  1. #!/bin/bash
  2. # Basic until loop
  3. counter=1
  4. until [ $counter -gt 10 ]
  5. do
  6. echo $counter
  7. ((counter++))
  8. done
  9. echo All done



  1. #!/bin/bash
  2. # Basic for loop
  3. names='Stan Kyle Cartman'
  4. for name in $names
  5. do
  6. echo $name
  7. done
  8. echo All done



  1. #!/bin/bash
  2. # Basic range in for loop
  3. for value in {1..5}
  4. do
  5. echo $value
  6. done
  7. echo All done



  1. #!/bin/bash
  2. # Basic range with steps for loop
  3. for value in {10..0..2}
  4. do
  5. echo $value
  6. done
  7. echo All done


  1. #!/bin/bash
  2. # Make a php copy of any html files
  3. for value in $1/*.html
  4. do
  5. cp $value $1/$( basename -s .html $value ).php
  6. done


  1. #!/bin/bash
  2. # Make a backup set of files
  3. for value in $1/*
  4. do
  5. used=$( df $1 | tail -1 | awk '{ print $5 }' | sed 's/%//' )
  6. if [ $used -gt 90 ]
  7. then
  8. echo Low disk space 1>&2
  9. break
  10. fi
  11. cp $value $1/backup/
  12. done


  1. #!/bin/bash
  2. # Make a backup set of files
  3. for value in $1/*
  4. do
  5. if [ ! -r $value ]
  6. then
  7. echo $value not readable 1>&2
  8. continue
  9. fi
  10. cp $value $1/backup/
  11. done



  1. #!/bin/bash
  2. # A simple menu system
  3. names='Kyle Cartman Stan Quit'
  4. PS3='Select character: '
  5. select name in $names
  6. do
  7. if [ $name == 'Quit' ]
  8. then
  9. break
  10. fi
  11. echo Hello $name
  12. done
  13. echo Bye




[Unix / Linux Shell Tutorial - Lession7] Arithmetic

  1. #!/bin/bash
  2. # Basic arithmetic using let
  3. let a=5+4
  4. echo $a # 9
  5. let "a = 5 + 4"
  6. echo $a # 9
  7. let a++
  8. echo $a # 10
  9. let "a = 4 * 5"
  10. echo $a # 20
  11. let "a = $1 + 30"
  12. echo $a # 30 + first command line argument

OperatorOperation
+, -, \*, /addition, subtraction, multiply, divide
var++Increase the variable var by 1
var--Decrease the variable var by 1
%Modulus (Return the remainder after division)
Example2
  1. #!/bin/bash
  2. # Basic arithmetic using expr
  3. expr 5 + 4
  4. expr "5 + 4"
  5. expr 5+4
  6. expr 5 \* $1
  7. expr 11 % 2
  8. a=$( expr 10 - 3 )
  9. echo $a # 7

Example3
  1. #!/bin/bash
  2. # Basic arithmetic using double parentheses
  3. a=$(( 4 + 5 ))
  4. echo $a # 9
  5. a=$((3+5))
  6. echo $a # 8
  7. b=$(( a + 3 ))
  8. echo $b # 11
  9. b=$(( $a + 4 ))
  10. echo $b # 12
  11. (( b++ ))
  12. echo $b # 13
  13. (( b += 3 ))
  14. echo $b # 16
  15. a=$(( 4 * 5 ))
  16. echo $a # 20


Example4
  1. #!/bin/bash
  2. # Show the length of a variable.
  3. a='Hello World'
  4. echo ${#a} # 11
  5. b=4953
  6. echo ${#b} # 4





[Unix / Linux Shell Tutorial - Lession6] If Statement

Anything between then and fi (if backwards) will be executed only if the test (between the square brackets) is true.
Let's look at a simple example:
  1. #!/bin/bash
  2. # Basic if statement
  3. if [ $1 -gt 100 ]
  4. then
  5. echo Hey that\'s a large number.
  6. pwd
  7. fi
  8. date

The square brackets ( [ ] ) in the if statement above are actually a reference to the command test. This means that all of the operators that test allows may be used here as well. Look up the man page for test to see all of the possible operators (there are quite a few) but some of the more common ones are listed below.
OperatorDescription
! EXPRESSIONThe EXPRESSION is false.
-n STRINGThe length of STRING is greater than zero.
-z STRINGThe lengh of STRING is zero (ie it is empty).
STRING1 = STRING2STRING1 is equal to STRING2
STRING1 != STRING2STRING1 is not equal to STRING2
INTEGER1 -eq INTEGER2INTEGER1 is numerically equal to INTEGER2
INTEGER1 -gt INTEGER2INTEGER1 is numerically greater than INTEGER2
INTEGER1 -lt INTEGER2INTEGER1 is numerically less than INTEGER2
-d FILEFILE exists and is a directory.
-e FILEFILE exists.
-r FILEFILE exists and the read permission is granted.
-s FILEFILE exists and it's size is greater than zero (ie. it is not empty).
-w FILEFILE exists and the write permission is granted.
-x FILEFILE exists and the execute permission is granted.
A few points to note:
  • = is slightly different to -eq. [ 001 = 1 ] will return false as = does a string comparison (ie. character for character the same) whereas -eq does a numerical comparison meaning [ 001 -eq 1 ] will return true.
  • When we refer to FILE above we are actually meaning a path. Remember that a path may be absolute or relative and may refer to a file or a directory.
Because [ ] is just a reference to the command test we may experiment and trouble shoot with test on the command line to make sure our understanding of its behaviour is correct.
Example2
  1. #!/bin/bash
  2. # Nested if statements
  3. if [ $1 -gt 100 ]
  4. then
  5. echo Hey that\'s a large number.
  6. if (( $1 % 2 == 0 ))
  7. then
  8. echo And is also an even number.
  9. fi
  10. fi

Example3
  1. #!/bin/bash
  2. # elif statements
  3. if [ $1 -ge 18 ]
  4. then
  5. echo You may go to the party.
  6. elif [ $2 == 'yes' ]
  7. then
  8. echo You may go to the party but be back before midnight.
  9. else
  10. echo You may not go to the party.
  11. fi

Sometimes we only want to do something if multiple conditions are met. Other times we would like to perform the action if one of several condition is met. We can accommodate these with boolean operators.
  • and - &&
  • or - ||
For instance maybe we only want to perform an operation if the file is readable and has a size greater than zero.
  1. #!/bin/bash
  2. # and example
  3. if [ -r $1 ] && [ -s $1 ]
  4. then
  5. echo This file is useful.
  6. fi

Example or
  1. #!/bin/bash
  2. # or example
  3. if [ $USER == 'bob' ] || [ $USER == 'andy' ]
  4. then
  5. ls -alh
  6. else
  7. ls
  8. fi

Example:case
  1. #!/bin/bash
  2. # case example
  3. case $1 in
  4. start)
  5. echo starting
  6. ;;
  7. stop)
  8. echo stoping
  9. ;;
  10. restart)
  11. echo restarting
  12. ;;
  13. *)
  14. echo don\'t know
  15. ;;
  16. esac

Now let's look at a slightly more complex example where patterns are used a bit more.
  1. #!/bin/bash
  2. # Print a message about disk useage.
  3. space_free=$( df -h | awk '{ print $5 }' | sort -n | tail -n 1 | sed 's/%//' )
  4. case $space_free in
  5. [1-5]*)
  6. echo Plenty of disk space available
  7. ;;
  8. [6-7]*)
  9. echo There could be a problem in the near future
  10. ;;
  11. 8*)
  12. echo Maybe we should look at clearing out old files
  13. ;;
  14. 9*)
  15. echo We could have a serious problem on our hands soon
  16. ;;
  17. *)
  18. echo Something is not quite right here
  19. ;;
  20. esac

[Unix / Linux Shell Tutorial ] Function

  1. #!/bin/bash
  2. # Basic function
  3. print_something () {
  4. echo Hello I am a function
  5. }
  6. print_something
  7. print_something


  1. ./function_example.sh
  2. Hello I am a function
  3. Hello I am a function


Passing Arguments

It is often the case that we would like the function to process some data for us. We may send data to the function in a similar way to passing command line arguments to a script. We supply the arguments directly after the function name. Within the function they are accessible as $1, $2, etc.
  1. #!/bin/bash
  2. # Passing arguments to a function
  3. print_something () {
  4. echo Hello $1
  5. }
  6. print_something Mars
  7. print_something Jupiter

  1. ./arguments_example.sh
  2. Hello Mars
  3. Hello Jupiter

Return Values

Most other programming languages have the concept of a return value for functions, a means for the function to send data back to the original calling location. Bash functions don't allow us to do this. They do however allow us to set a return status. Similar to how a program or command exits with an exit status which indicates whether it succeeded or not. We use the keyword return to indicate a return statu
  1. #!/bin/bash
  2. # Setting a return status for a function
  3. print_something () {
  4. echo Hello $1
  5. return 5
  6. }
  7. print_something Mars
  8. print_something Jupiter
  9. echo The previous function has a return value of $?

Line 11 - Remember that the variable $? contains the return status of the previously run command or function.
  1. ./return_status_example.sh
  2. Hello Mars
  3. Hello Jupiter
  4. The previous function has a return value of 5

Example2
  1. #!/bin/bash
  2. # Setting a return value to a function
  3. lines_in_file () {
  4. cat $1 | wc -l
  5. }
  6. num_lines=$( lines_in_file $1 )
  7. echo The file $1 has $num_lines lines in it.

Let's break it down:
  • Line 5 - This command will print the number of lines in the file referred to by $1.
  • Line 8 - We use command substitution to take what would normally be printed to the screen and assign it to the variable num_lines
  1. cat myfile.txt
  2. Tomato
  3. Lettuce
  4. Capsicum

  5. ./return_hack.sh myfile.txt
  6. The file myfile.txt has 3 lines in it.

Example3
  1. #!/bin/bash
  2. # Experimenting with variable scope
  3. var_change () {
  4. local var1='local 1'
  5. echo Inside function: var1 is $var1 : var2 is $var2
  6. var1='changed again'
  7. var2='2 changed again'
  8. }
  9. var1='global 1'
  10. var2='global 2'
  11. echo Before function call: var1 is $var1 : var2 is $var2
  12. var_change
  13. echo After function call: var1 is $var1 : var2 is $var2

  1. ./local_variables.sh
  2. Before function call: var1 is global 1 : var2 is global 2
  3. Inside function: var1 is local 1 : var2 is global 2
  4. After function call: var1 is global 1 : var2 is 2 changed again

Friday, November 29, 2019

[Unix / Linux Shell Tutorial - Lession5] Variables

Example 1: test.sh
  1. #!/bin/bash
  2. echo $1 $2

Now run it: ./test.sh => Nothing print in Terminal
./test.sh Hello => Hello string was show
./test.sh Hello World => Hello World was show

For instance we could run the command ls -l /etc-l and /etc are both command line arguments to the command ls. We can do similar with our bash scripts. To do this we use the variables $1 to represent the first command line argument, $2 to represent the second command line argument and so on. These are automatically set by the system when we run our script so all we need to do is refer to them.

  1. #!/bin/bash
  2. # A simple copy script
  3. cp $1 $2

Line 4 - run the command cp with the first command line argument as the source and the second command line argument as the destination.

There are a few other variables that the system sets for you to use as well.
  • $0 - The name of the Bash script.
  • $1 - $9 - The first 9 arguments to the Bash script. (As mentioned above.)
  • $# - How many arguments were passed to the Bash script.
  • $@ - All the arguments supplied to the Bash script.
  • $? - The exit status of the most recently run process.
  • $$ - The process ID of the current script.
  • $USER - The username of the user running the script.
  • $HOSTNAME - The hostname of the machine the script is running on.
  • $SECONDS - The number of seconds since the script was started.
  • $RANDOM - Returns a different random number each time is it referred to.
  • $LINENO - Returns the current line number in the Bash script.
If you type the command env on the command line you will see a listing of other variables which you may also refer to.


Exporting Variable

script1.sh
  1. #!/bin/bash
  2. var1=blah
  3. var2=foo
  4. echo $0 :: var1 : $var1, var2 : $var2
  5. export var1
  6. ./script2.sh


script2.sh
  1. #!/bin/bash
  2. echo $0 :: var1 : $var1, var2 : $var2


Note: the name of variable must be same with both sh file.


Wednesday, November 27, 2019

fgets() and gets() in C language

fgets() and gets() in C language

For reading a string value with spaces, we can use either gets() or fgets() in C programming language. Here, we will see what is the difference between gets() and fgets().
fgets()
It reads a line from the specified stream and stores it into the string pointed to by str. It stops when either (n-1) characters are read, the newline character is read, or the end-of-file is reached, whichever comes first.
Syntax :
char *fgets(char *str, int n, FILE *stream)
str : Pointer to an array of chars where the string read is copied.
n : Maximum number of characters to be copied into str 
(including the terminating null-character).
*stream : Pointer to a FILE object that identifies an input stream.
stdin can be used as argument to read from the standard input.

returns : the function returns str
  • It follow some parameter such as Maximum length, buffer, input device reference.
  • It is safe to use because it checks the array bound.
  • It keep on reading until new line character encountered or maximum limit of character array.
Example : Let’s say the maximum number of characters are 15 and input length is greater than 15 but still fgets() will read only 15 character and print it.



// C program to illustrate
// fgets()
#include <stdio.h>
#define MAX 15
int main()
{
    char buf[MAX];
    fgets(buf, MAX, stdin);
    printf("string is: %s\n", buf);
  
    return 0;
}
Since fgets() reads input from user, we need to provide input during runtime.
Input:
Hello and welcome to Embeded


Output:
Hello and welc
gets()
Reads characters from the standard input (stdin) and stores them as a C string into str until a newline character or the end-of-file is reached.
Syntax:
char * gets ( char * str );
str :Pointer to a block of memory (array of char) 
where the string read is copied as a C string.
returns : the function returns str
 
  • It is not safe to use because it does not check the array bound.
  • It is used to read string from user until newline character not encountered.
Example : Suppose we have a character array of 15 characters and input is greater than 15 characters, gets() will read all these characters and store them into variable.Since, gets() do not check the maximum limit of input characters, so at any time compiler may return buffer overflow error.



// C program to illustrate
// gets()
#include <stdio.h>
#define MAX 15
  
int main()
{
    char buf[MAX];
  
    printf("Enter a string: ");
    gets(buf);
    printf("string is: %s\n", buf);
  
    return 0;
}
Since gets() reads input from user, we need to provide input during runtime.
Input:
Hello and welcome to Embeded

Output:
Hello and welcome to Embeded
Back to Top