DEV Community

Malhar Gupte
Malhar Gupte

Posted on

Shell Scripting for Beginners: From Zero to Automating Your First Tasks (Part 1)

Introduction

There's a moment every developer eventually hits — you find yourself doing the same repetitive task for the tenth time that week. Maybe it's renaming a batch of files, SSHing into servers and running the same commands, or cleaning up log directories. You do it manually, again, and somewhere in the back of your head a little voice says: "There has to be a better way."

That better way is shell scripting.

Shell scripting is one of those foundational skills that quietly separates developers who feel comfortable on a Linux system from those who feel like they're just guessing. It's not glamorous. It won't land you on the front page of Hacker News. But the ability to write a script that saves you 20 minutes every day? Over a year, that's more than 120 hours back in your pocket.

For DevOps engineers and sysadmins, scripting isn't optional — it's oxygen. Deployments, backups, health checks, log rotation, user provisioning — all of it gets automated with shell scripts. But even if you're a backend developer or just getting started with Linux, learning to write basic scripts will make your day-to-day dramatically more efficient.

This guide is Part 1 of a two-part series. We're going to go from "what even is a shell?" to writing a working script that takes arguments, reads user input, and does real arithmetic — all from scratch. No experience needed.

Let's get into it.


What is a Shell Script?

Before we write anything, let's get the vocabulary straight.

The Shell

When you open a terminal on Linux or macOS, you're not talking directly to the operating system kernel. There's a program sitting in between — that's the shell. It reads the commands you type, interprets them, and tells the OS what to do.

Think of it like a translator. You speak "human command language," the shell translates it, and the OS executes it.

Bash

There are several shell programs out there — sh, zsh, fish, dash — but the one you'll encounter most in the wild, especially on Linux servers, is Bash (Bourne Again SHell). It's been around since 1989, it's installed on virtually every Linux system, and it's what most shell scripting tutorials (including this one) use.

When you open a terminal and start typing commands, there's a very good chance you're already using Bash.

# Check which shell you're currently using
echo $SHELL

# Check your bash version
bash --version
Enter fullscreen mode Exit fullscreen mode

What is a Shell Script?

A shell script is just a plain text file that contains a series of commands — the same commands you'd type in a terminal, but saved in a file so they can be run all at once, on demand, automatically.

That's it. There's no compiling, no special runtime. It's text that the shell reads and executes line by line.

Why is Scripting So Powerful?

  • Repeatability — Run the exact same sequence of commands every time, with no typos or forgotten steps.
  • Automation — Schedule scripts to run at 3am without you being there.
  • Speed — What takes you 10 manual commands takes a script half a second.
  • Portability — A script that works on one Linux server will usually work on another.

Creating Your First Script

Time to write something. Open your terminal and follow along.

Step 1: Create the Script File

A shell script is just a file. By convention, shell script files end with .sh, though technically the extension doesn't matter to the shell.

# Create a new file called hello.sh
touch hello.sh

# Open it in a text editor
nano hello.sh
Enter fullscreen mode Exit fullscreen mode

Add the following content:

#!/bin/bash

echo "Hello, World!"
echo "My first shell script is running."
Enter fullscreen mode Exit fullscreen mode

Save and exit (Ctrl+O, then Ctrl+X in nano).

Step 2: Make It Executable

By default, a new file doesn't have execute permission. If you try to run it as-is, you'll get a "Permission denied" error. You need to tell Linux that this file is allowed to be executed:

chmod +x hello.sh
Enter fullscreen mode Exit fullscreen mode

chmod stands for change mode. The +x adds execute permission for the file owner. You only have to do this once per script.

Tip: Run ls -l hello.sh before and after chmod +x to see the permissions change. You'll notice an x appear in the permission string.

Step 3: Run the Script

Now you can execute it:

./hello.sh
Enter fullscreen mode Exit fullscreen mode

You should see:

Hello, World!
My first shell script is running.
Enter fullscreen mode Exit fullscreen mode

The ./ prefix tells the shell to look for the file in the current directory. Without it, the shell would only look in directories listed in your $PATH environment variable.

Alternative: You can also run it as bash hello.sh — this works even without chmod +x. But using ./ with execute permissions is the standard practice.


Understanding the Shebang

You probably noticed the first line of the script:

#!/bin/bash
Enter fullscreen mode Exit fullscreen mode

This is called the shebang (also written as "hashbang"). It's not a comment, even though it starts with #. It's a special directive for the operating system.

How It Works

When you execute a file, the OS looks at the very first two characters. If it sees #!, it knows: "This is a script — the path that follows tells me which interpreter to use."

So #!/bin/bash is saying: "Use the program located at /bin/bash to execute this script."

If you were writing a Python script instead, you might use:

#!/usr/bin/env python3
Enter fullscreen mode Exit fullscreen mode

Or for a Node.js script:

#!/usr/bin/env node
Enter fullscreen mode Exit fullscreen mode

Always Include It

Some scripts will run without a shebang, but the behavior depends on whatever shell happens to be running them — which can vary between systems. Always include #!/bin/bash at the top of your Bash scripts. It makes your script's behavior explicit and predictable.

#!/bin/bash

# Your script starts here
echo "Shebang ensures I always run with Bash"
Enter fullscreen mode Exit fullscreen mode

Tip: Use which bash to find the exact path to Bash on your system. On most systems it's /bin/bash, but on some (like certain macOS setups with Homebrew) it might be /usr/local/bin/bash. Using #!/usr/bin/env bash is a more portable alternative that searches your $PATH for bash.


Variables in Shell Scripts

Variables let you store values and reuse them. In Bash, they're simple to declare — maybe a little too simple, because the syntax is strict and easy to get wrong at first.

Declaring a Variable

#!/bin/bash

name="Malhar"
age=21
city="Vadodara"
Enter fullscreen mode Exit fullscreen mode

Rules to live by:

  • No spaces around the = sign. name = "Malhar" will fail. It must be name="Malhar".
  • Variable names are case-sensitive. Name and name are different variables.
  • By convention, use lowercase for regular script variables and UPPERCASE for environment variables and constants.

Using a Variable

To use (or "reference") a variable, prefix its name with $:

#!/bin/bash

name="Malhar"
city="Vadodara"

echo "Hello, my name is $name and I live in $city."
Enter fullscreen mode Exit fullscreen mode

Output:

Hello, my name is Malhar and I live in Vadodara.
Enter fullscreen mode Exit fullscreen mode

Curly Brace Syntax

When a variable name could be ambiguous — like when you're placing it right next to other text — wrap it in curly braces:

#!/bin/bash

animal="dog"

echo "I have one ${animal}."
echo "I have two ${animal}s."   # Without braces, $animals would fail
Enter fullscreen mode Exit fullscreen mode

Output:

I have one dog.
I have two dogs.
Enter fullscreen mode Exit fullscreen mode

Tip: Get in the habit of using ${variable} over $variable — it prevents subtle bugs and makes your scripts easier to read.

Storing Command Output in a Variable

This is a technique you'll use constantly — capturing the output of a command into a variable:

#!/bin/bash

current_date=$(date)
current_user=$(whoami)

echo "Script run by: $current_user"
echo "Date: $current_date"
Enter fullscreen mode Exit fullscreen mode

The $(...) syntax runs the command inside and captures its output. This is called command substitution.


Command Line Arguments

Scripts become far more useful when they can accept input at the time you run them — without needing to edit the file.

How Arguments Work

When you run a script like this:

./greet.sh Alice DevOps
Enter fullscreen mode Exit fullscreen mode

Bash automatically populates special variables:

Variable Value Description
$0 ./greet.sh The name of the script itself
$1 Alice First argument
$2 DevOps Second argument
$3 (empty) Third argument (not provided here)
$# 2 Total number of arguments passed
$@ Alice DevOps All arguments as a list

Example Script

Create a file called greet.sh:

#!/bin/bash

echo "Script name: $0"
echo "Hello, $1! You work in $2."
echo "Total arguments passed: $#"
Enter fullscreen mode Exit fullscreen mode

Make it executable and run it:

chmod +x greet.sh
./greet.sh Alice DevOps
Enter fullscreen mode Exit fullscreen mode

Output:

Script name: ./greet.sh
Hello, Alice! You work in DevOps.
Total arguments passed: 2
Enter fullscreen mode Exit fullscreen mode

What if an Argument Isn't Provided?

If $1 is empty because no argument was given, your script might behave unexpectedly. A good practice (which we'll cover more in Part 2 with conditionals) is to provide a default:

#!/bin/bash

name=${1:-"stranger"}   # Use $1 if provided, otherwise default to "stranger"

echo "Hello, $name!"
Enter fullscreen mode Exit fullscreen mode
./greet.sh           # → Hello, stranger!
./greet.sh Malhar    # → Hello, Malhar!
Enter fullscreen mode Exit fullscreen mode

Tip: ${variable:-default} is a Bash parameter expansion trick. The :- means "use this default value if the variable is unset or empty." Keep this one handy.


Taking Input from the User

Sometimes you want the script to pause and ask the user something while it's running. That's what the read command is for.

Basic read

#!/bin/bash

echo "What is your name?"
read user_name
echo "Nice to meet you, $user_name!"
Enter fullscreen mode Exit fullscreen mode

The script will wait after printing the question. When the user types something and hits Enter, whatever they typed gets stored in user_name.

read -p (Prompt on the Same Line)

The -p flag lets you combine the prompt and the input on the same line, which looks cleaner:

#!/bin/bash

read -p "Enter your name: " user_name
read -p "Enter your city: " user_city

echo ""
echo "Welcome, $user_name from $user_city!"
Enter fullscreen mode Exit fullscreen mode

Output (with user input in italics):

Enter your name: Malhar
Enter your city: Vadodara

Welcome, Malhar from Vadodara!
Enter fullscreen mode Exit fullscreen mode

read -s (Silent Input)

For sensitive input like passwords, use -s to hide what the user types:

#!/bin/bash

read -sp "Enter your password: " user_pass
echo ""
echo "Password received (not printing it, obviously)."
Enter fullscreen mode Exit fullscreen mode

Arithmetic Operations in Bash

Bash handles arithmetic a bit differently than most programming languages. The most reliable and readable way to do arithmetic is with the $(( )) syntax.

Basic Operations

#!/bin/bash

a=10
b=3

echo "Addition:       $((a + b))"
echo "Subtraction:    $((a - b))"
echo "Multiplication: $((a * b))"
echo "Division:       $((a / b))"   # Integer division only
echo "Modulo:         $((a % b))"
echo "Exponentiation: $((a ** b))"
Enter fullscreen mode Exit fullscreen mode

Output:

Addition:       13
Subtraction:    7
Multiplication: 30
Division:       3
Modulo:         1
Exponentiation: 1000
Enter fullscreen mode Exit fullscreen mode

Important: Bash only does integer arithmetic by default. $((10 / 3)) gives you 3, not 3.333. If you need decimal math, use bc or awk — we'll touch on those in later parts of this series.

Storing Arithmetic Results

#!/bin/bash

width=8
height=5

area=$((width * height))
perimeter=$(( 2 * (width + height) ))

echo "Width: $width, Height: $height"
echo "Area: $area"
echo "Perimeter: $perimeter"
Enter fullscreen mode Exit fullscreen mode

Output:

Width: 8, Height: 5
Area: 40
Perimeter: 26
Enter fullscreen mode Exit fullscreen mode

Increment and Decrement

#!/bin/bash

count=0

((count++))    # Increment by 1
echo $count    # 1

((count += 5)) # Add 5
echo $count    # 6

((count--))    # Decrement by 1
echo $count    # 5
Enter fullscreen mode Exit fullscreen mode

Putting It All Together: A Small Practical Script

Let's combine everything we've covered — variables, arguments, user input, and arithmetic — into one cohesive script.

Scenario: You're building a simple tool for a gym management system. It takes a member's name and monthly fee as arguments, asks how many months they're signing up for, and calculates the total cost.

Create a file called gym_membership.sh:

#!/bin/bash

# ─────────────────────────────────────────
# gym_membership.sh
# Usage: ./gym_membership.sh <name> <monthly_fee>
# ─────────────────────────────────────────

# Grab arguments
member_name=${1:-"Member"}
monthly_fee=${2:-0}

echo "========================================="
echo "       Gym Membership Calculator"
echo "========================================="
echo ""
echo "Welcome, $member_name!"
echo "Monthly fee: ₹${monthly_fee}"
echo ""

# Ask for duration
read -p "How many months are you signing up for? " months

# Calculate totals
total=$((monthly_fee * months))
annual_equivalent=$((monthly_fee * 12))

echo ""
echo "-----------------------------------------"
echo "  Membership Summary"
echo "-----------------------------------------"
echo "  Name:               $member_name"
echo "  Monthly Fee:        ₹${monthly_fee}"
echo "  Duration:           ${months} months"
echo "  Total Cost:         ₹${total}"
echo "  (Annual would be:   ₹${annual_equivalent})"
echo "-----------------------------------------"
echo ""
echo "Registration complete. See you at the gym!"
Enter fullscreen mode Exit fullscreen mode

Make it executable and run it:

chmod +x gym_membership.sh
./gym_membership.sh Malhar 999
Enter fullscreen mode Exit fullscreen mode

Sample output:

=========================================
       Gym Membership Calculator
=========================================

Welcome, Malhar!
Monthly fee: ₹999

How many months are you signing up for? 6

-----------------------------------------
  Membership Summary
-----------------------------------------
  Name:               Malhar
  Monthly Fee:        ₹999
  Duration:           6 months
  Total Cost:         ₹5994
  (Annual would be:   ₹11988)
-----------------------------------------

Registration complete. See you at the gym!
Enter fullscreen mode Exit fullscreen mode

This is a real, working script. Not a toy. You could drop this into a server right now and use it.


Conclusion

Let's recap what you've learned in Part 1:

  • What a shell script is — a plain text file with commands that the shell executes line by line
  • The shebang (#!/bin/bash) — tells the OS which interpreter to use
  • Creating and running scriptstouch, chmod +x, and ./script.sh
  • Variables — declaring with name="value", referencing with $name or ${name}
  • Command line arguments$0, $1, $2, $#, and default values with ${1:-default}
  • User inputread, read -p, and read -s
  • Arithmetic$(( )) for clean integer math

These are the building blocks. Every shell script you'll ever write — no matter how complex — is made up of some combination of these fundamentals.


What's Coming in Part 2

We've only just scratched the surface. In Part 2, we're going to add the real logic that turns scripts from simple command sequences into actual automation tools:

  • Conditional logicif, elif, else to make decisions
  • Loopsfor and while to repeat actions
  • Case statements — cleaner multi-branch logic
  • Functions — reusable blocks of code
  • Exit codes — how scripts communicate success or failure
  • Real automation scripts — backing up directories, monitoring disk usage, batch processing files

By the end of Part 2, you'll have scripts worth actually putting into a cron job.


Found this helpful? Drop a like or a comment — it genuinely helps. And if you're following along and something isn't working the way you expect, ask in the comments. Shell scripting has some gotchas that trip everyone up the first time.

See you in Part 2.

Top comments (0)