6  Shell Scripting

6.1 Introduction

Shell scripting is a powerful tool for automating tasks in Linux. This section introduces the basics of creating and executing shell scripts using the nano text editor.

Overview:

  • Learn to write your first script with basic commands.
  • Understand script execution permissions and debugging.
  • Explore script enhancement by adding it to the $PATH.
  • Manipulate variables and perform mathematical calculations.
  • Handle user input and conditional logic.


6.2 Writing Your First Script

Begin by generating a new script file:

nano myscript.sh

For your script:

  • Begin with #!/bin/bash for the interpreter.
  • Add # for comments.

Basic script example:

#!/bin/bash
# List files and directories
ls

To save your script, use Ctrl + O, and exit nano with Ctrl + X.

6.3 Running Your Script

Make the script executable:

chmod +x myscript.sh

Run the script:

./myscript.sh

Debug the script:

bash -x myscript.sh

6.4 Adding Scripts to $PATH

To run your script from anywhere:

export PATH=$PATH:/path/to/script

After this, you can execute your script just by typing its name:

myscript.sh

6.5 Working with Variables

To use variables in your script:

#!/bin/bash
name="Alice"
echo $name

For Multi-line Texts:

To print multi-line texts, use echo -e and \n for new lines:

#!/bin/bash
greeting="Hello\neveryone"
echo -e $greeting

6.6 Working with Quotes

In Bash, quotation marks can alter how text is interpreted:

  • ' ': Single quotes
  • " ": Double quotes
  • ` `: Backticks

The behavior of variables and commands changes based on the quotes used:

6.6.1 Single Quotes

Using single quotes:

message="Good morning"
echo 'The message is: $message'

Produces:

The message is: $message

Single quotes prevent variable expansion, treating $message as literal text.

6.6.2 Double Quotes

Using double quotes:

message="Good morning"
echo "The message is: $message"

Produces:

The message is: Good morning

Double quotes allow for variable expansion, so $message is replaced with its value.

6.6.3 Backticks

Backticks execute the command within and capture its output:

message=`pwd`
echo "The working directory is: $message"

Produces a message like:

The working directory is: /home/user

Backticks run the command pwd and assign its output to message.

6.7 Capturing User Input

The read command in Bash scripts is designed to capture input from the user and store it in variables.

6.7.1 Basic Usage

Simply use read followed by a variable name to store the user’s input:

read name

In this example, the user’s input is stored in the variable name.

6.7.2 Storing Input in Multiple Variables

You can capture input into multiple variables like so:

read name var2 var3

This command waits for a single line of input, which is then split by spaces and stored in name, var2, and var3 respectively.

6.7.3 Options for read

Prompting with -p:

You can display a prompt message before capturing input:

#!/bin/bash

read -p 'Enter your name: ' name
echo "Good morning, $name!"

Limiting Input with -n:

Limit the number of characters the user can input:

#!/bin/bash

read -p 'Enter your name (5 characters max): ' -n 5 name
echo -e "\nGood morning, $name!"

Timeout with -t:

Set a time limit for the input:

#!/bin/bash

read -p 'Enter your name (within 5 seconds): ' -t 5 name
echo -e "\nGood morning, $name!"

Silent Input with -s:

For sensitive information, like passwords, use -s to hide the input:

#!/bin/bash

read -p 'Enter your password: ' -s pass
echo -e "\nThank you, your password has been recorded."

6.8 Performing Arithmetic

Bash supports basic arithmetic using the let command:

#!/bin/bash

let "a = 5"
let "b = 7"
let "c = a + b"
echo $c

In this example, c will output the sum of a and b, which is 12.

6.8.1 Arithmetic Operators:

  • +: Addition
  • -: Subtraction
  • *: Multiplication
  • /: Division
  • **: Exponentiation
  • %: Modulus

You can also use shorthand notation, where let "a = a * 2" is equivalent to let "a *= 2".

6.9 Accessing Script Parameters

Scripts can accept parameters, accessible via special variables:

./yourscript.sh param1 param2 param3
  • $#: Number of parameters passed to the script
  • $0: The script’s name (./yourscript.sh in this case)
  • $1, $2, $3, etc.: The first, second, third (and so on) parameter

6.10 Working with Arrays

Arrays in Bash can be utilized for storing and accessing multiple values:

# Declare an array
array=("value0" "value1" "value2")

# Access an element
echo ${array[2]}  # Outputs 'value2'

# Modify an element
array[2]="newValue"

# Print all elements
echo ${array[*]}  # Outputs all elements in the array

Arrays offer a flexible way to work with collections of data in your scripts.

6.11 Working with Conditions

6.11.1 Basic if Statement

The if statement checks for a condition and executes a block of code if the condition is true:

name="Robert"

if [ "$name" == "Robert" ]; then
    echo "Hi Robert"
fi

6.11.2 Nested if Statements

You can nest if statements within each other or use elif for additional conditions:

if [ condition1 ]; then
    # Code block for condition1
elif [ condition2 ]; then
    # Code block for condition2
else
    # Default code block
    if [ condition4 ]; then
        # Nested if
    fi
fi

6.11.3 String Comparisons

Test Description
$var1 == $var2 Check if var1 equals var2
$var1 != $var2 Check if var1 is not equal to var2
-z $var1 Check if var1 is empty
-n $var1 Check if var1 is not empty

6.11.4 Numeric Comparisons

Test Description
$num1 -eq $num2 num1 is equal to num2
$num1 -ne $num2 num1 is not equal to num2
$num1 -lt $num2 num1 is less than num2
$num1 -gt $num2 num1 is greater than num2
$num1 -le $num2 num1 is less than or equal to num2
$num1 -ge $num2 num1 is greater than or equal to num2

6.11.5 File Tests

Test Description
-e $file Check if file exists
-d $file Check if file is a directory
-f $file Check if file is a regular file
-L $file Check if file is a symbolic link
-r $file Check if file is readable
-w $file Check if file is writable
-x $file Check if file is executable
$file1 -nt $file2 Check if file1 is newer than file2
$file1 -ot $file2 Check if file1 is older than file2

6.11.6 Combining Tests

  • Use && for logical AND
  • Use || for logical OR

6.11.7 Negating a Test

Use ! to negate a test:

if [ ! -e "$file" ]; then
    echo "The file doesn't exist"
fi

6.11.8 Using case for Multiple Conditions

The case statement is useful for matching one variable against multiple patterns:

case $var in
    "Bruno")
        echo "Hello Bruno"
        ;;
    "Michel")
        echo "Hello Michel"
        ;;
    "Jean")
        echo "Hello Jean"
        ;;
    *)
        echo "I don't know you"
        ;;
esac

6.11.9 Loops

While Loop:

while [ condition ]; do
    # Commands
done

For Loop:

Loop through a list of values:

for variable in value1 value2 value3; do
    echo "The variable is $variable"
done

Loop through files in the current directory:

for file in $(ls); do
    echo "File found: $file"
done

Loop with a sequence:

for i in $(seq 1 10); do
    echo $i
done

6.12 Conclusion

By learning shell scripting, you can automate repetitive tasks, making your Linux experience more productive and enjoyable.