Shell scripting basics

How to automate the shell using scripts

view on github

Basic concepts

✔️ Running shell scripts

  • Any command that can be executed from the shell may be placed into a script and behave exactly the same (and vice versa)
  • A script must have the execute permission x set for the current user before it may be run.
  • It is important to note a script started from the command line doesn't run in the current shell process, instead a new shell is started and runs the script.
  • A notable exception to the above is what is called "sourced scripts".

✔️ Writing shell scripts

  • The first line of any shell script has to be the shebang #! followed by the path to interpreter :
#!/bin/bash

echo "some script"
  • That line identifies the interpreter to use and should never contain any additional character
  • Shell comments are prefixed with #

Bash scripts are particularly picky when it comes to formatting. Make sure spaces are put where they are needed and not put when they are not needed.

✔️ Using vi as an editor

  • There are two modes in vi : insert (or input) mode and edit mode.
  • In input mode you may input or enter content into the file.
  • In edit mode you can move around the file, perform actions such as deleting, copying, search and replace, saving etc...
  • vi regexp uses Vim syntax

Control flow

✔️ Basics

  • Built in control structures in the shell are more or less the same as in any other programming language
  • They differ in that the expressions used do not evaluate through operators but are instead based on test expressions
  • Those expressions can perform various tests on variables, files, etc ... as seen below

✔️ Control structures list

  • if conditional structure
# if a file exists in my home directory ... 
if [ -f "$HOME/myfile" ]; then
    # run commands ...
fi
  • while loop structure
# as long as a variable is greater than zero ... 
while [ $counter -gt 0 ]; do
    # run commands ...
done
  • until loop structure
# as long as a variable is different than zero ... 
until [ $counter -eq 0 ]; do
    # run commands ...
done
  • for loop structure
# execute a sequence of instructions for each value in a list or an array ...
# reference the value inside the loop by using $value ...
for value in $list; do
    # run commands ...
done
  • case conditional structure
case $var in
    # if $var equals value1 ...
    value1)
        # run commands ...
        ;;
    # if $var equals value2 ...
    value2)
        # run commands ...
        ;;
    # if $var is different ...
    *)
        # run commands ...
        ;;
esac
  • Notes :
    • When using the bash shell, it's best to wrap up expressions in double brackets (although single brackets work too)
    • One of the most useful applications of for loops is the processing of a set of files (wildcards and shell globbing allow that).
    • break and continue keywords are available in bash loops, as they are in many other languages to the same effect.

Essential features

✔️ Functions

  • Shell functions accept a list of words as argument so as multiple parameters can be passed
function some_function {
    # variable local to a functionare not accessible from outside
    # do stuff ...
}
# call the function and pass a word list as argument
some_function some arguments and more for a total of 4
  • Function parameters are accessible within the function as $1, $2, etc ... like in a normal script
  • The function definition must appear in the script before any calls to the function
  • Shell functions do no return values but exit codes like any other linux process
  • Workaronds to retrieve values from functions exist, such as this :
function sample_function {
    # print return value to the function's stdout
    echo "function actual return value" > /dev/stdout
    # "return" a success code
    return 0
}
# use command substitution to read a value from the function
result=$(sample_function)

✔️ Operators

  • Type let --help to view the list of supported arithmetic, logical and bitwise operators.
  • Evaluation of expressions that use operators can be performed in 2 ways
# evaluate an expression and store the result in a variable with let
let var="4 + 2"
# prints 6
echo $var
# wrap the expression in parentheses and run command substitution on it
# prints 1 for true
echo $((5 != 3))
  • ${#var} returns the length of a variable

✔️ User input

  • User input can be processed by the shell using the read command
  • read prompts user for input and then assigns the input values to variables
# ask for user name, first name and employment
echo "Please enter your name and first name:"
read -r lname fname
echo "Please enter your profession:"
read -r empl
  • User input will be processed as a list of words, each word being assigned to the variables which were passed as arguments to read
  • If there are more words than variable, the remaining words will all be added to the last variable
  • If there are less words than variable, the remaining variable names will be set to blank or null
  • read comes with a variety of options (for instance -p to specify a prompt and -s to make the input silent)