Skip to content
DevOps devops shell 5 min read

What is Bash & Shell Scripting?

Every command you type into a Linux terminal is a small instruction to the computer. A shell script is just a text file that holds a list of those same commands, so the computer can run them for you — in order, every time, without you typing them by hand. In DevOps (the practice of automating how software is built, deployed, and operated), this is the foundation everything else is built on. If you can type it once, you can script it forever.

What is a shell?

A shell is the program that reads what you type, runs it, and shows you the result. When you open a terminal on an Ubuntu server, a shell is already waiting for you. It is the layer between you and the operating system (the core software, Linux, that manages the machine).

The most common shell on Linux is Bash — short for Bourne Again SHell. It is the default interactive shell on Ubuntu 22.04 and 24.04 LTS (LTS means “Long-Term Support”, a release Canonical maintains for years). You can confirm which shell you are using:

echo "$SHELL"

Output:

/bin/bash

What is a shell script?

A shell script is a plain text file containing the commands you would otherwise type one by one. Instead of running three commands manually every morning, you save them in a file and run the file. The computer executes each line top to bottom.

Here is the difference in practice. Typing manually:

sudo apt update
sudo apt upgrade -y
sudo systemctl restart nginx

The same thing saved as a script called update-server.sh:

#!/bin/bash
sudo apt update
sudo apt upgrade -y
sudo systemctl restart nginx

Now you run it with one command instead of three:

./update-server.sh

That first line, #!/bin/bash, is called a shebang. It tells Linux which program should run the file. You will learn more about it in Shebang and execution.

Why automation matters in DevOps

Automation is not about laziness — it is about correctness and scale. A human running ten commands by hand will eventually mistype one, skip one, or do them in the wrong order. A script does the exact same thing every single time.

Manual commandsShell scripts
Easy to forget a stepEvery step runs, in order
Different each time a person does itIdentical, repeatable result
Hard to share with teammatesJust send the file
No record of what was doneThe file IS the documentation
Slow on many serversRun on 100 servers the same way

These benefits map to the core reasons DevOps engineers script everything:

  • Repeatability — the same input always produces the same output.
  • Fewer mistakes — no fat-fingered typos at 2 a.m. during an incident.
  • Speed — what took five minutes by hand runs in five seconds.
  • Documentation — the script records exactly how a task is done.
  • Scale — one script can configure one server or one thousand.

When to use a script vs. typing by hand: If you have done a task more than twice, or you will need to do it on more than one machine, write a script. For a true one-off you will never repeat, typing directly is fine.

Bash vs sh vs other shells

People often say “shell script” and “Bash script” as if they are the same thing, but they are not. sh is the original, minimal POSIX shell (POSIX is a standard that defines a baseline set of features every Unix-like shell must support). Bash is a newer, much more powerful shell that includes everything sh has, plus many extras like arrays and richer string handling.

ShellWhat it isWhen to use it
sh (dash on Ubuntu)Minimal POSIX shell, very fast, very portableBoot scripts, maximum portability across Unix systems
bashFeature-rich, the default interactive shellMost automation; what this section teaches
zshBash-compatible with extra interactive featuresPersonal interactive use; popular with developers
fishFriendly, modern, NOT POSIX-compatibleInteractive comfort, not for portable scripts

On Ubuntu, /bin/sh is actually dash (a small, fast sh implementation), not Bash. This matters: a script written with Bash-only features will break if run with sh. You can see the difference here:

ls -l /bin/sh

Output:

lrwxrwxrwx 1 root root 4 Jun 15 09:12 /bin/sh -> dash

Gotcha: Never run a Bash script with sh script.sh. That forces it through dash, and any Bash-specific syntax (like [[ ... ]] or arrays) will fail with cryptic errors. Always start your script with #!/bin/bash and run it as ./script.sh.

Everything you type can be scripted

This is the key mindset shift. There is no special “scripting language” separate from the commands you already use. The commands you type interactively — apt, systemctl, cp, grep, ufw — are the exact same commands you put in a script. A script is just those commands saved to a file.

That means the moment you learn a useful command at the terminal, you have also learned a line of a future script. Managing the systemd service manager (the tool Ubuntu uses to start and stop background services), opening firewall ports with ufw (Uncomplicated Firewall), copying config into /etc/nginx/sites-available — all of it can be wrapped in a script and run on demand or on a schedule.

#!/bin/bash
# A tiny but complete real script: back up Nginx config with a timestamp
backup_dir="/var/backups/nginx"
sudo mkdir -p "$backup_dir"
sudo cp -r /etc/nginx "$backup_dir/nginx-$(date +%Y%m%d-%H%M%S)"
echo "Backup complete."

Output:

Backup complete.

Once a script like this exists, you can run it from a scheduler with cron so it happens automatically every night — no human needed.

Best Practices

  • Start every Bash script with the #!/bin/bash shebang so it always runs with the right shell.
  • Give scripts clear, descriptive names ending in .sh, like deploy-app.sh, not s1.sh.
  • Add short # comments explaining why a step exists, not just what it does.
  • Test a new script on a throwaway server or in a safe directory before running it on production.
  • Quote your variables ("$var") to avoid surprises with spaces and empty values.
  • Keep each script focused on one job; chain small scripts rather than building one giant file.
  • Store scripts in version control (Git) so changes are tracked and reviewable.
Last updated June 15, 2026
Was this helpful?