My Shell Guide

In this blog post, we will cover some essential aspects of the Bash shell, including basic commands, conditional statements, loops, and special variables. This will serve as a handy reference for those who might forget certain details or want to learn more about Bash scripting.

Basics of Bash Shell

Shebang

A shebang (#!) is added at the beginning of a shell script to specify the shell interpreter to use. Common options include sh or bash.

#!/bin/sh
#!/bin/bash

Shebangs can also include optional parameters:

#!/bin/sh -x

Even non-shell scripts, such as PHP scripts, can have a shebang:

#!/usr/bin/env php

Variables

In Bash, all variables are treated as strings.

# No space after the variable name or after the equal sign.
a=123

# This command is the same as the one above:
a="123"

# For strings with spaces or special characters that need to be escaped, use quotes
a="I know, I know\nWhat's next?"

To assign a variable to another variable:

# Use quotes
b="$a"

# Combine with other literals
b="a is like: $a"

# In case `a` doesn't have a space around it
b="How many ${a}s do you have again?"

Assigning a variable from command output:

a="Today is $(date +%Y-%d-%m)"

Conditional Statements (if)

Bash provides several ways to write conditions, including [], test, [[]], let, and (()).

General syntax for an if statement:

if CONDITION
then
    # Do something
fi

# Condition and `then` can be on the same line
if CONDITION ; then
    # Do something
fi

# Include an `else` section
if CONDITION ; then
    # Do A
else
    # Do B
fi

Using [] or test

# Test if $a and 123 are equal
if [ $a = "123" ]
# For bash, you can use:
if [ $a == "123" ]

# `test` is equivalent to `[]`
if test $a = "123"

# Test if $a and 123 are not equal
if [ $a != "123" ]

# Test if $a is an empty string
if [ -z $a ]

# Test if $a is NOT an empty string
if [ -n $a ]
# or
if [ ! -z $a ]

# Numeric comparisons:
# If $a equals $b
if [ $a -eq $b]
# If $a and $b are not equal
if [ $a -ne $b]
# If $a is greater than $b
if [ $a -gt $b]
# If $a is greater or equal to $b
if [ $a -ge $b]
# If $a is less than $b
if [ $a -lt $b]
# If $a is less or equal to $b
if [ $a -le $b]

# Logical operators:
# If $a equals 1 and $b equals 2 (does NOT short-circuit)
if [ $a = 1 -a $b = 2 ]
# or (short-circuits)
if [ $a = 1 ] && [ $b = 2 ]

# If $a equals 1 or $b equals 2 (does NOT short-circuit)
if [ $a = 1 -o $b = 2 ]
# or (short-circuits)
if [ $a = 1 ] || [ $b = 2 ]

# If `$dir` is an existing directory path
if [ -d "$dir"]

# If `$file_path` is not an existing file path
if [ ! -f "$file_path"]

Using [[]]

The [[]] notation is specific to Bash and ksh and was introduced in Bash version 2.02. It provides more expressive capabilities than [].

# Use wildcards
if [[ $a = 12* ]] # Matches `123`, `12f2`, `12dsa`, etc.
if [[ $a = 12? ]] # Matches `123`, `12f`, `12w`, etc.

# Use a literal asterisk by quoting it
if [[ $a = "12*" ]] # Matches `12*` only

# Compare using standard math notations
if [[ $a > $b ]]

# Use logical operators inside the brackets (short-circuits)
if [[ $a = 1 && $b = 2 ]]
# or (short-circuits)
if [[ $a = 1 ]] && [[ $a = 2 ]]

Using (())

The (()) notation is for arithmetic calculations, and its result can be used as a logical value for an if statement.

# Omit the dollar sign for variables and use a more flexible syntax
if ((a==10))

# The single equal sign `=` means assignment here
if ((a=1)) # This will always be true, and $a will become 1

# More complex examples:
if ((a>6 && b<10))
if ((a/3==4))

while Loops

Understanding conditions for if statements makes understanding while loops easy. until loops are similar to while loops but run only when the condition is NOT met.

while CONDITION
do
    # Repeatedly do something
done

# A simple example
while ((i <= 100))
do
    ((sum += i))
    ((i++))
done

# Same thing using until
until ((i > 100))
do
    ((sum += i))
    ((i++))
done

# Use `continue` and `break`
until ((i > 100))
do
    ((sum += i))
    ((i++))
    if ((i==40)) ; then
        break
    else
        continue
    fi
done

for Loops

for loops in Bash come in two styles: one similar to C/C++, and the other similar to Python. You can also use break and continue.

C-style for loop

for ((i=1; i<=100; i++))
do
    ((sum += i))
done

Python-style for loop

# List values
for n in 1 2 3 4 5 6
do
    echo $n
     ((sum+=n))
done

# Can be strings (numbers are also strings)
for str in "a" "b" "c"
do
    echo $str
done

# Can be a range
for n in {1..100}
do
    ((sum+=n))
done

# Or range of characters (in the order of ASCII codes)
for c in {A..z}
do
    echo $c # This will include []^_`
done

# Can also use the result of a command
for filename in $(ls *.sh)
do
    echo $filename
done

Unix Special Variables

VariableDescription
$0The filename of the current script.
$nThese variables correspond to the arguments with which a script was invoked. Here n is a positive decimal number corresponding to the position of an argument (the first argument is $1, the second argument is $2, and so on).
$#The number of arguments supplied to a script.
$*All the arguments, all double quoted. If a script receives two arguments, $* is equivalent to $1 $2.
$@All the arguments, all individually double quoted. If a script receives two arguments, $@ is equivalent to $1 $2.
$?The exit status of the last command executed.
$$The process number of the current shell. For shell scripts, this is the process ID under which they are executing.
$!The process number of the last background command.

Snippets

Get the script path:

shell_dir=$(dirname "$0")

Delete a directory if it exists:

if [ -d "$dir" ] ; then
  rm -rf "$dir"
fi

Create a directory if it doesn't exist:

if [ ! -d "$dir" ] ; then
  mkdir -p "$dir"
fi

In conclusion, this blog post has covered the basics of Bash shell scripting, including variables, conditional statements, loops, and special variables. With this knowledge, you can create powerful and efficient scripts for various tasks. Remember to refer back to this post as a handy reference whenever you need a refresher on Bash shell scripting.

NoticeMy website is currently under construction. Some features may not work as expected.