Let’s talk with Bash!

Reading Time: 4 minutes

Bash is one of several well-known UNIX shells, its wide distribution with Linux makes it an important tool to know. It is an improved bourne shell and incorporates useful features from the Korn shell and the C shell. Let’s get started and talk with bash in some effective ways.

What is Scripting?

It basically involves writing a series of commands that are interpreted one by one at runtime, unlike programming languages that are compiled first before running.

Lets say Hello in Bash

The first line of every script should provide the path to the interpreter after the Shebang (#!) and we can even pass arguments as well.
It could be written in the following syntax:

#!interpreter-path [arguments]


For example, create a script file save it with the .sh extension and the below code.

#!/bin/bash -x
echo "Hello bash!!!"

To execute the above script you can either use bash my-script.sh or ./myscipt.sh. Also, don’t forget to give execute permissions.

Note: -x is an argument to interpreter and can used to run script in debug mode

Use it right and be wise.!!!

Although Bash is primarily a command interpreter, it’s also a feature-rich programming language. It supports variables, functions and has control flow constructs, such as conditional statements and loops. Now let’s explore some ways that can be used to make scripting life a bit easier.

How to use variables in Bash?

A variable is nothing more than a pointer to the actual data. The bash enables you to create, assign, and delete variables.
Types of variables

  • Local − it is visible only within the block of code and is declared using local keyword in a small case.
  • Global − it is visible in the same shell scope and is declared without any keyword in a small case.
  • Environment −it is available to any child process of the shell and is declared using export keyword in upper case.
  • Static/Readonly – these are similar to constant variables and is declared using readonly

Note: The upper/lower case is used just to follow scripting standards. Also unset can be used to remove value from a variable.

How to make decisions ?

Decision making is all based on conditional constructs and how you use them logically in the correct order. Bash supports various kind of operators such as arithmetic, relational, file test, etc. It also supports various conditional constructs such as if, switch/case and loops. Let’s discuss what we usually miss out.

  • Ternary Operator
    • firstly, bash doesn’t have such operator.
    • if/else can be used in short notation just to have a feel of the ternary operator.
    • Syntax
[[ condition ]] && 'true statement' || 'false statement'

Some ignored loops .!!!

A loop is a powerful programming tool that enables you to execute a set of commands repeatedly.

  • The until loop
    • executes a set of commands until a condition is true.
    • works just opposite of while loop
    • For example print numbers up to n
#!/bin/bash 

i=1
n=10
until [ $i -ge $n ]; do
    echo "$i"
    let "i++"
done
}
  • The select loop
    • it provides an easy way to create a numbered menu from which users can select options.
    • It is useful when you need to ask the user to choose one or more items from a list of choices.
    • For example
#!/bin/bash 

HISTORY=Start
select PAGE in Home Login Admin Student Faculty Exam Result Close
do
    HISTORY=$HISTORY-\>$PAGE
    if [[ $PAGE = Close ]]
    then
        break
    else
        echo "Currently you are on $PAGE page."
    fi
done
echo "Your browsing history is : $HISTORY"

Make functions a habit

Functions enable you to break down the overall functionality of a script into smaller, logical subsections, which can then be called upon to perform their individual tasks when needed.

Functions can be defined in two ways :

function_name () {
    #commands
}
OR
function function_name {
    #commands
}

Pass Parameters to a Function

#!/bin/bash
foo(){ 
   echo "Parameters received :  $1 $2"  
}
foo Hello Bash 

Returning Values from Functions
Based on the situation you can return any value from your function using the return command which can be captured by $? from where the function is called. It is a very good practice to follow. For example, consider following

#!/bin/bash
add(){
    local sum=`expr $1 + $2`
    return $sum
}
add 10 20
sum=$?
echo "Sum is $sum"

Array in Bash

Arrays is a collection of variables referred positionally by a common name.

  • Declaration Syntax declare -a array_name OR array_name=[value1,value2,....valueN]
  • Common usage syntax
    arr=() // Create an empty array
  • ${#arr[@]} // Calculate array size
    arr[0]=3 // Overwrite 1st element
    arr+=(4) // Append value(s)
    ${arr[@]:s:n} // Retrieve n elements starting at index s
  • For example, let’s iterate over an array
#!/bin/bash
arr=(1 sam 3 4 5)
for i in ${arr[@]}
do
     echo $i
done

Do more with Dictionaries in Bash

Dictionary/Associative arrays/Hashmap are very useful key-value based data structures and they can be created in bash.

  • Syntax: $ declare -A dictionary_name
  • Adding key-value pairs: $ dictionary_name[key]=value
  • Retrieve key-values: echo ${dictionary_name[key]}
  • Delete a key in a dictionary: unset dictionary_name[key]
  • For example
#/bin/bash
foo-dict() {
    declare -A person
    person=([name]=sam [age]=10 [gender]=male)  
    echo ${person["name"]}  // prints sam
    echo "All values are  : ${person[@]} "
    unset person[age]  // deletes a pair
    echo "All values are  : ${person[*]} "
    echo "All keys are  : ${!person[*]} "
    unset person  // delete complete person
}
foo-dict

Flags: Always there to Rescue

It is always recommended to used set or use flags in your script as they help in many ways. We can use – and + with set to enable/ disable the flags. These flags can be passed as arguments to the interpreter.

Some of the frequently used flags are:

  • x: it is used for debugging mode
    • can be set while calling the script
    • for example, bash -x myscript.sh
    • a section of lines can also be enclosed in script
    • set -x: starts the debugging mode
    • set +x: stop the debugging mode
  • v: it is used to run the script in verbose mode and display each command prior to execution.
  • u: it can be used to report an error if a variable doesn’t exist as bash ignores such variables by default.
  • e: it can be used to terminate the script whenever an error is encountered.
    • By default, bash continues to run the script.
    • this flag doesn’t apply to commands clubbed via pipe ( | ).
  • o: it can be used to invoke various other option for which direct flags may/may not be available.
    • set -o pipefail: this will fail the entire pipeline if any of the sub-command fails.
    • set -o xtrace: same as to set -x
    • set -o nounset: similar to set -u
    • set -o verbose: similar to set -v
  • n: it can be used to run the script without executing the steps/commands.
    • it can be used to check for syntactical errors.
Knoldus

References