A shell script is simply a text file containing a sequence of commands that the shell (like Bash) can execute. Instead of typing multiple commands repeatedly, you put them in a script and run the script.

The Shebang #! (Sha Bang!):

Every good magic spell needs an incantation, right? For shell scripts, that's the shebang. It's the very first line of your script and tells the system which interpreter should be used to run the commands that follow. For Bash scripts, it usually looks like this:

#!/bin/bash

Or sometimes:

#!/usr/bin/env bash

This line ensures that your script is run with the Bash shell, even if the user running it has a different default shell.

To make your script runnable, you'll need to give it execute permission:

chmod +x your_script_name.sh

And then you can run it:

./your_script_name.sh

Variables: Naming Your Digital Treasures 💰

Variables are like labeled boxes where you can store information (text, numbers) that you want to use later in your script.

Defining Variables:

You define a variable by giving it a name and assigning a value using the equals sign. Important: No spaces around the = sign!

myname="Captain Coder"
age=30

Accessing Variables:

To use the value stored in a variable, you put a dollar sign $ in front of its name.

#!/bin/bash
greeting="Hello"
planet="World"
echo "$greeting, $planet!" # Outputs: Hello, World!

user_name="AdaLovelace"
echo "Welcome, $user_name" # Outputs: Welcome, AdaLovelace

Environment and Shell Variables:

  • Environment Variables: These are available system wide and to all child processes spawned by the shell. They often define things like your default editor (EDITOR), your command search path (PATH), or your home directory (HOME). You can see them by typing env or printenv. They are usually in ALL CAPS.
  • Shell Variables: These are typically set within the current shell instance and are not automatically passed to child processes unless explicitly exported.

Special Friends: Positional & Special Variables ✨

Shell scripts have some built in special variables that provide useful information:

  • Positional Parameters: These let you access arguments passed to your script when you run it from the command line.

    • $0: The name of the script itself.
    • $1, $2, $3, ... $9: The first, second, third... ninth argument passed to the script.
    • ${10} and beyond: For arguments beyond the ninth, you need to use curly braces.

    Example Script (greet_user.sh):

    #!/bin/bash
    echo "Hello, $1! Welcome to the script named $0."
    echo "You provided $# arguments."
    

    Running it: ./greet_user.sh Alice

    Output:

    Hello, Alice! Welcome to the script named ./greet_user.sh.
    You provided 1 arguments.
    
  • Other Special Variables:

    • $#: The total number of positional parameters (arguments) passed to the script.
    • $* or $@: All positional parameters as a single string ($*) or as separate quoted strings ($@ which is usually preferred).
    • $?: The exit status of the last command executed. A 0 usually means success, and any non zero value means an error. This is super important for checking if commands worked!
    • $$: The Process ID (PID) of the current shell (the script itself).
    • $!: The PID of the last backgrounded command.

Command Substitution: Capturing Command Output 🎣

Sometimes you want to use the output of a command as part of another command or assign it to a variable. This is called command substitution. The modern way to do this is using $(command).

#!/bin/bash
current_date=$(date +"%Y-%m-%d")
echo "Today's date is: <span class="math-inline">current\_date"
files\_in\_dir\=</span>(ls)
echo "Files in current directory are: <span class="math-inline">files\_in\_dir"
user\_count\=</span>(who | wc -l)
echo "There are $user_count users logged in."

In each case, the command inside $(...) is executed, and its output replaces the $(...) part.

Making Your Scripts Smart: Arithmetic, Conditionals & Loops 🧠🔄

Now for the really fun stuff: making your scripts think and repeat actions!

Basic Arithmetic:

You can perform arithmetic using ((...)) or let.

#!/bin/bash
num1=10
num2=5

((sum = num1 + num2))
echo "Sum: $sum" # Output: Sum: 15

((product = num1 * num2)) # Note the * for multiplication
echo "Product: $product" # Output: Product: 50

let diff=num1-num2
echo "Difference: $diff" # Output: Difference: 5

Conditional Statements (Making Decisions):

  • if statements: Allow you to execute commands based on a condition.

    The basic structure is if [ condition ]; then ... fi.

    #!/bin/bash
    age=18
    if [ "$age" -ge 18 ]; then # -ge means greater than or equal to
      echo "You are an adult."
    else
      echo "You are a minor."
    fi
    

    Common comparison operators for numbers:

    • -eq: equal
    • -ne: not equal
    • -lt: less than
    • -le: less than or equal to
    • -gt: greater than
    • -ge: greater than or equal to

    For string comparisons:

    • =: equal (or == inside [[ ... ]])
    • !=: not equal
    • -z string: true if string is empty
    • -n string: true if string is not empty
  • case statements: Useful when you have multiple choices based on the value of a single variable. It's like a cleaner way to write multiple if/elif/else statements.

    #!/bin/bash
    fruit="apple"
    case "$fruit" in
      "apple")
        echo "It's a juicy red apple."
        ;;
      "banana")
        echo "It's a sweet yellow banana."
        ;;
      "orange")
        echo "It's a tangy orange."
        ;;
      *) # Default case
        echo "It's some other fruit."
        ;;
    esac
    

Loops (Repeating Actions):

  • for loops: Iterate over a list of items or a range.

    #!/bin/bash
    # Looping through a list of strings
    for color in red green blue
    do
      echo "Color: $color"
    done
    
    # Looping through numbers (Bash specific sequence)
    for i in {1..3}
    do
      echo "Number: $i"
    done
    
  • while loops: Keep executing commands as long as a condition is true.

    #!/bin/bash
    counter=1
    while [ "$counter" -le 3 ] # -le means less than or equal to
    do
      echo "Counter is $counter"
      ((counter++)) # Increment counter
    done
    

These fundamentals are the building blocks for creating some truly amazing automations. The best way to learn is by doing, so open up a text editor, start with that #!/bin/bash, and make your computer work for you! 🚀