Shell Script Quick Reference

Shell Script can be very helpful in automating day to day tasks.
If you have exposure to programming then getting into the Shell scripting is fairly easy but can sometimes be tricky. Specially due to all the gimmicks it has under its sleeves, which are intended to make tasks easier(and they do) but takes a programmer, who has no prior knowledge of shell scripting by surprise.

This article is more about how to get things done in Shell Script when you already have exposure to other programming language but can be helpful for anyone starting out with Shell scripting.

In case you have no prior experience in scripting or programming, check out the article Think Programming to understand why these concepts exists.

Here’s a quick reference to the constructs present in Shell Scripting to get you to understand and write scripts quickly.

Let’s start with the basics. A shell script is simply a text file.

The lines of the file are read in and interpreted by the shell, much as if someone had typed in the same lines directly at a terminal.

The first line is treated specially, in that it can identify the shell interpreter to be used to execute the remainder of the file. Examples include:

#!/bin/bash – Tells the system that the script is to be executed using the bash(Bourne Again) shell.

#!/bin/sh – Tells the system that the script is to be executed using the bourne shell.

The specified shell will read in, interpret, and execute the content of the script. In all shell languages, lines which start with # are comments, so the interpreters have no problem ignoring that first line when they see it.

We set the scripts file permissions +x and in combination with using that special first line, that’s all it takes for us to add a new command to our system. Well, there’s a little more – you will want to ensure the script file is in a directory that’s mentioned in your $PATH

Variables

Naming a variable –  By convention, all cap names should be used for environment variables eg : MY_ENV_VAR (shell variables that are “exported”), while shell local variable names should be all lower case eg : my_var.
Accessing a variable – $MY_ENV_VAR , $my_var

  • – It is better to use ${my_msg} compared to $my_msg. This will be helpful in cases where you want to append a string with your variable and create let’s say a filename out of it based on user input. So you could essentially do touch ${my_msg}_file
  • – If you try to use the variable which doesn’t exist then it prints an empty value. In your script, use set -u at the next line of #!/bin/bash , which displays the error if any variables are unset, it saves you time in debugging.
  • – If the values of the variables are changed in a script, then the value outside of the script will not be changed. You need to source the script for changes to take effect. run the script as $ . ./myscript.sh
  • – When using strings as values, use quotes.

Reserved Variables

  • – $0 – holds the base name of the program
  • – $1 …. $9 – are the parameters passed to the program
  • [email protected] – lists all parameters
  • – $# – number of parameters script was called with
  • – $? – Another special variable is $?. This contains the exit value of the last run command.
  • – $$  — variable is the PID – Process IDentifier of the currently running shell.
  • – $! — The $! variable is the PID of the last run background process. This is useful to keep track of the process as it gets on with its job.
  • Note that the value of $0 changes depending on how the script was called.

Escape Character

  • \ Is treated as escape character in shell scripts when used with double quotes.
  • – If you want to escape *, ” etc. then use \ to escape
  • – Character $, `, and \ are interpreted by the shell even when they are inside the double quotes.

for Loop

For loop will loop over any kind of data .. it does not have to be restricted to a particular type of data type.

for i in 1 2 hello 
do
    echo $i
done

You can also write the above as :

for i in 1 2 hello; do
​ echo $i
done

while Loop

#!/bin/bash
VAR_A=1
while [ ${VAR_A} -ne 5 ]
do
        VAR_A=`expr ${VAR_A} + 1`
        echo hello + ${VAR_A}
done
  • [ ] – denotes the test condition, your exit condition goes in between.
  • Spaces are important : <space>[<space> <exit condition> after <space>]<space>
  • [ is a symbolic link to test – a binary, hence the spacing around the [ ] is important, this isn’t the part of shell syntax but something test demands.
  • – Using : with while instead of exit condition, always evaluates to true. replace 3rd line with while :

if-else Statements

if [ … ]
then 
    #do something
else
#do something else
fi

You can also shorten the syntax by writing first two line as shown below.

if [ … ]; then  
    #do something
else
#do something else
fi

Using elif

if [ … ]; then 
    # do something
elif [ … ]; then
    # do something
else
    #do something
fi

Again Spaces are important : <space>[<space> <condition> after <space>]<space>

You can also use the condition logic in the following manner.

[ $Y -gt 0 ] && echo "Y isn't zero" || echo "Y is greater than zero" 

CASE Statement

case $INPUT_STRING in
        one)
                echo 1
                ;;
        two)
                echo 2
                ;;
        *)
                echo "no match found"
                ;;
esac 

Arrays

ANIMALS=( ‘cat’ ‘dog’ ‘rat’ )

  • – echo ${ANIMALS[0]} – prints cat
  • – echo ${ANIMALS[@]} – prints all animals in list separated by space
  • – echo ${#ANIMALS[@]} – prints number of element
  • – echo ${#ANIMALS[2]} . – prints length of second element

Array Operations

  • – ANIMALS+=( ‘cow’ ) – add an item to the list.
  • – ANIMALS=(“${ANIMALS[@]}” “cow”) – another way to add an item
  • – ANIMALS=( ${ANIMALS[@]/dog/} ) – remove an item by name
  • unset ANIMALS[1] – remove item by index
  • – ANIMALS=(“${ANIMALS[@]}” “${BIRDS[@]}”) – concatenate two lists

Array Iteration

for i in "${ANIMALS[@]}"; do
echo $i
done

Functions

Defining Functions

sampleFunc() {
echo "hello world"
}

You can also define a function as shown below:

function sampleFunc() {
echo "hello world"
}

Note that while using function keyword, () becomes optional, but is mandatory when function keyword is not used.

Passing arguments to a function

sampleFunc() {
echo "hello $1"
}

sampleFunc "world"
  • – Here the “world” will be passed as argument to the function, and to use it in a function use $1, $2 etc. depending on the number of argument.
  • – Use $# to get the number of arguments
  • – Use $* to get all the arguments
  • – Use [email protected] to get all arguments from a list

Returning values from functions

function sampleFunc() {
MY="world"
echo $MY
}
output="$(sampleFunc)"
echo $output
  • – To raise/return an error from a function use return 1
  • – returning 0 on success is a convention

Conditional Flags and Comparisons

  • – [ -n STRING ] – not empty string
  • – [ -z STRING ] – empty string
  • – [ STRING1 = STRING2 ] – equal to
  • – [ STRING1 != STRING2 ] – not equal to
  • – [ int1 -eq int2 ] – equal to
  • – [ int1 -ne int2 ] – not equal
  • – [ int1 -gt int2 ] – greater than
  • – [ int1 -lt int2 ] – less than
  • – [ int1 -le int2 ] – less than or equal to
  • – [ int1 -ge int2 ] – greater than or equal to
  • – [ file1 -ot file2] – older than
  • – [ file1 -nt file2] – newer than

Miscellaneous

  • ShellCheck, a static analysis tool for shell scripts
  • \ – or splitting lines for better readability
  • read VAR_A – read input value for VAR_A
  • `<some command>` – runs in a sub shell. You can use it to insert command within double quotes
  • IFS – Internal Field Separator – default is Space, New line and Tab
  • -en – using -en to echo tells it to exclude the newline.
  • echo -en : “-n” alone will exclude the newline. “-e” is a different argument. By convention, after a single hyphen, each character is a separate argument (so “-en” is the same as “-e -n”), while after a double hyphen, the entire string is a single argument (so “–help” is one argument, not a series of four arguments). Finally, a double hyphen alone is an indication that everything following is a non-option argument (so “rm — -r” will remove a file named “-r” rather than treating “-r” as an indication that recursive removal was requested.)
  • :- – to specify a default value to be used. If the value of the variable is not set. ${VAR_A:-abc} – if the VAR_A is not set then it will be set to abc.
  • := – for setting and using a default value to a variable
  • – shift – shifts all arguments to left by one place. $2 becomes $1 , and original $1 gets deleted.
  • – $((VAR_A++)) – increases the value of VAR_A by 1
  • – $((VAR_A–)) – decreases the value of VAR_A by 1
  • – export $VAR_A – makes VAR_A available to all the new subprocesses
  • #!/bin/bash -x – enables debugging in your script
  • #!/bin/bash -n – checks the syntax of script without running any commands

If you want to get in depth knowledge about shell script, then refer https://www.shellscript.sh/

If you want to know more about shell scripts from the interview point of view then refer this article from medium.

Last but not the least, a huge thanks to the following reddit users who helped in making this post better. warpigg, gordonmessmer, xiongchiamiov, Secondsemblance, SaintHax42, CSI_Tech_Dept , SmileItsYourDay and TyMac711.

Please leave your feedback in comments section. Subscribe to the blog to get the notifications on new posts.

One Reply to “Shell Script Quick Reference”

  1. This is very well done man. I like all the reserved vars section. Just keep adding in good fuel to this and it could be a defacto resource. Thank you

Leave a Reply