Why should you learn to write bash scripts

We are already in 2022/23 and I have not written anything for 2 years. You all may now (assumptions) be using Docker or K8s and by definition may have to run a bunch of commands everyday and that is a good reason you learn about writting Bash scripts even if that sounds scary to you and you do not want to, at some point you will be confronted to it, working for a new team or a new company.

Basics

variable

Declaring a variable seems easy but in bash do not introduce any whitespace before and after the = character.

bad

myVar= "hello"
myVar ="hello"
myVar = "hello"

good

myVar="hello"

Referencing a variable is done through the $ character with $myVar

You can read more here about the local variables

function

Bash (shell) scripts support functions and I would advocate adopting them as often as you can to make your code cleaner and easier to read, a very hard thing with bash scripts.

Syntax is straighforward and there is no need to declare arguments or returned type.

function my_lovely_function() {
    // do stuff
}

Passing parameters to your function is obviously possible but calling your function is a bit special

// example with no parameters, not that () are omitted
my_lovely_function
// example with parameters
my_lovely_function "hello" "world"

Capturing parameters passed to your function is done through the $ keyword which takes a digit from 0 up to …I do not know the limit.

function my_lovely_function() {
    echo $0
    echo $1
    echo $2
}

my_lovely_function "hello" "world"

// will return
// my_lovely_function
// hello
// world

Note that $0 returns the name of your function

condition

There is documentation everywhere but here are the main I have been using so far for dealing with if/else condition statement.

Testing that a variable is empty with -z, other options exist like -n -v

myVar=""
[[ -z "$myVar" ]] && echo "myVar is empty dude"

// the opposite with !

myVar="toto"
[[ ! -z "$myVar" ]] && echo "myVar is not empty dude"

This previous version is built with double bracket syntax and there are many other options available with parenthesis…

The default would look more like

myVar=""

if [ -z "$myVar" ]
then
    echo "myVar is empty dude"
fi

// the opposite with !

myVar="toto"
if [ ! -z "$myVar" ]
then
    echo "myVar is not empty dude"
fi

Comparing 2 variables can be done this way

a=1
b=1
[[ $a == $b ]] && echo "values are equal"

// due to word-splitting better to wrap your variables with double quotes

a=1
b=1
[[ "$a" == "$b" ]] && echo "values are equal"

Command execution

The power of shell/bash scripting consist in automating repeatable tasks you do not want to run by yourself all day long.

You may want to run a curl command to fetch some data, or run a process locally like ls or create some files, there is no limit other than your imagination.

echo "line1\nline2\nline3" > file.txt
head -n 3 file.txt

$(command) is key for storing the result of your command execution into a variable

echo "line1\nline2\nline3" > file.txt
firstFewLines=$(head -n 3 file.txt)
echo $firstFewLines

combining multiple commands

firstFewLines=$(echo "line1\nline2\nline3" > file.txt && head -n 3 file.txt)
echo $firstFewLines

using a function and returning the execution of a command is another good trick and the easiest way seems to be this one with echo

function give_me_few_lines() {
    local firstFewLines=$(echo "line1\nline2\nline3" > file.txt && head -n 3 file.txt)
    # note that wrapping with quotes is important
    echo "$firstFewLines"
}

myVar=$(give_me_few_lines)
echo $myVar

Command line

Once you got a valid script you are proud of why not adding option so you can run it differently.

# to display usage
./myBashScript -h 
# dynamically display a custom number of lines
./myBashScript -l 1
./myBashScript -l 2
./myBashScript -l 3

script

To create a new script file named myBashScript.sh just use some bash instructions?

echo '#!/bin/bash\n\necho ready for coding in bash!' > ./myBashScript.sh && chmod +x ./myBashScript.sh && ./myBashScript.sh
  • echo to generate the content
  • > to redirect the output to a file (» to append)
  • chmod to give execute permission …
#!/bin/bash

echo ready for coding in bash!

script options

getopts builtin function is there for that

Previous given example would become like


function usage() {
    __usage="
    Usage: $0 [ -l LINE COUNT ]

    Options:
    -l <count>       Number of lines
    -h                Help
    "
    echo "$__usage" 1>&2
}

function exit_abnormal() {
    usage
    exit 1
}

function give_me_few_lines() {
    echo "line1\nline2\nline3" > file.txt && head -n $1 file.txt
}

while getopts "l:" options; do
    case "${options}" in
        l)
        give_me_few_lines ${OPTARG}
        exit 0
        ;;
        h)
        exit_abnormal
        ;;
        :)
        exit_abnormal
        ;;
        *)
        exit_abnormal
        ;;
    esac
done

Conclusion

There are plenty of things I have not talked about but I will do my best adding few more tips.

Terminal


Tags: Bash Shell

Written on hey December 28, 2022