DEV Community

ak0047
ak0047

Posted on

Essential Shell Scripting Basics You Should Know First

Introduction

I previously wrote an article about shell scripting, and to my surprise, it was read by far more people than I expected.
Since shell scripting isn’t exactly a “trendy” technology, I assumed there wouldn’t be much interest.

That experience made me realize:

There are probably more people who want to learn shell scripting than we think.

So in this article, I’d like to share a digest of essential shell scripting basics.

This guide is designed to cover “the minimum you need to know to avoid getting stuck when writing your first shell script.”
Rather than going deep into each topic, I focus on breadth and practical awareness.

This article is especially useful if you:

✅ Have never written a shell script before
✅ Tried once but struggled
✅ Want to understand how shell scripting differs from other languages


Basic Rules of Shell Scripts

The .sh Extension Is a Convention

Technically, shell scripts can have any file extension.
However, .sh is the widely accepted convention.

hello.sh
backup.sh
deploy.sh
Enter fullscreen mode Exit fullscreen mode

Using .sh enables syntax highlighting in editors and on GitHub, so unless you have a specific reason not to, stick with it.

Write a Shebang (#!) on the First Line

A shell script should start with a shebang:

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

The shebang specifies which shell should execute the script.
It starts with #! followed by the full path to the shell.

One Command Per Line

In shell scripts, a newline separates commands, so the basic rule is one command per line.

If you want to split a command across multiple lines, use \:

echo "This is \
one command"
Enter fullscreen mode Exit fullscreen mode

Comments Use #

Comments start with #. You can also place comments mid-line.

There is no native way to comment out multiple lines at once.

# This is a comment
echo "hello" # inline comments are allowed
Enter fullscreen mode Exit fullscreen mode

Working with Variables

Defining Variables

Variables are created automatically using:

variable_name=value
Enter fullscreen mode Exit fullscreen mode

No declaration is required.

Variable naming rules:

  • Allowed characters: letters, numbers, and _
  • Cannot start with a number
  • Lower snake_case is commonly used
  • Variables are treated as strings by default

If you want an integer variable, you need to declare it explicitly:

# String variable
sum=2+9
echo $sum
# -> 2+9

# Integer variable
declare -i sum
sum=2+9
echo $sum
# -> 11
Enter fullscreen mode Exit fullscreen mode

Referencing Variables

To reference a variable, prefix it with $:

name="Alice"
echo $name
# -> Alice
Enter fullscreen mode Exit fullscreen mode

In bash, referencing an undefined variable does not cause an error—it expands to an empty string:

echo $name
# -> (empty output)
Enter fullscreen mode Exit fullscreen mode

To clearly separate variable names from surrounding text, use {}:

item="pen"
echo "I have many ${item}s"
Enter fullscreen mode Exit fullscreen mode

Single vs Double Quotes

Quotes behave differently depending on the type:

  • " : variables are expanded
  • ' : variables are not expanded
name="Alice"
echo "$name"
# -> Alice

echo '$name'
# -> $name
Enter fullscreen mode Exit fullscreen mode

To escape characters inside double quotes, use \:

echo "\$name"
# -> $name
Enter fullscreen mode Exit fullscreen mode

Common Control Structures

Conditional Branching (if / case)

if Statements

if [ condition ]; then
  do_something
elif [ another_condition ]; then
  do_something_else
else
  fallback
fi
Enter fullscreen mode Exit fullscreen mode

There are two condition styles ([] and [[]]).
If you’re curious about the difference, see this article:
https://dev.to/a-k-0047/whats-the-difference-between-and-in-shell-scripts-3kkj

case Statements

case is useful when handling multiple patterns:

case "$var" in
  start)
    echo "start"
    ;;
  stop)
    echo "stop"
    ;;
  *)
    echo "other"
    ;;
esac
Enter fullscreen mode Exit fullscreen mode

Loops (for / while)

for Loop

for value in a b c; do
  echo $value
done
Enter fullscreen mode Exit fullscreen mode

while Loop

declare -i count=0

while [ $count -lt 5 ]; do
  echo $count
  count=$count+1
done
Enter fullscreen mode Exit fullscreen mode

An infinite loop can be written like this:

while true; do
  echo "looping..."
  sleep 1
done
Enter fullscreen mode Exit fullscreen mode

Functions

Functions are defined as follows:

hello() {
  echo "Hello $1 and $2"
}
Enter fullscreen mode Exit fullscreen mode

Arguments are accessed using $1, $2, $3, and so on.

Calling a function:

hello "Alice" "Bob"
# -> Hello Alice and Bob
Enter fullscreen mode Exit fullscreen mode

Shell-Specific Concepts

Exit Status

On Linux, every command returns an exit status.

  • 0 → success
  • Non-zero → failure

The exit status is not displayed automatically.
You can check it using $?:

ls /usr
# -> bin  libexec  sbin  standalone  X11R6  lib  local  share  X11
echo $?
# -> 0

ls /aaa
# -> ls: /aaa: No such file or directory
echo $?
# -> 1
Enter fullscreen mode Exit fullscreen mode

When using exit status in if statements:

  • 0 is treated as true
  • Non-zero is treated as false
if ls /usr; then
  echo "success"
else
  echo "failure"
fi
# -> success

if ls /aaa; then
  echo "success"
else
  echo "failure"
fi
# -> failure
Enter fullscreen mode Exit fullscreen mode

Command Substitution

You can store command output in a variable using $(...):

now=$(date)
echo $now
# -> Fri Dec 12 19:47:14 JST 2025
Enter fullscreen mode Exit fullscreen mode

Pathname Expansion (Globbing)

Shells can expand patterns like * and ? into multiple filenames.

Examples:

ls
# -> file1.txt file2.txt string.c string.h string.txt

# ? matches a single character
ls string.?
# -> string.c string.h

# * matches any string
ls *.txt
# -> file1.txt file2.txt string.txt

# [] matches one of the listed characters
ls string.[ch]
# -> string.c string.h
Enter fullscreen mode Exit fullscreen mode

Running Shell Scripts Manually

There are two main ways to execute a shell script.

Method 1: Execute Directly (Recommended)

./hello.sh
Enter fullscreen mode Exit fullscreen mode
  • Specify the script path (relative or absolute)
  • Executed using the shebang-defined shell
  • Requires execute permission: chmod +x hello.sh
  • Script name alone is not enough
✅ ./hello.sh
❌ hello.sh
Enter fullscreen mode Exit fullscreen mode

Method 2: Pass to the Shell

bash hello.sh
Enter fullscreen mode Exit fullscreen mode
  • Execute permission not required
  • You must manually choose the correct shell

Conclusion

This article summarized the minimum knowledge needed to avoid getting stuck when writing your first shell script.

There are many more important patterns and techniques to learn, so I plan to write follow-up articles that dive deeper into specific topics.


💬 How about you?

  • What was the most confusing part of shell scripting when you first learned it?
  • Are there any shell scripting rules or behaviors that surprised you?
  • Would you like to see a deeper article on a specific topic (e.g. if conditions, quoting, or debugging)?

Top comments (0)