A Windows admin opens a ticket for a Linux box, a Synology, an Azure VM or a CI runner and lands in a terminal that does not answer to PowerShell. The prompt says bash and every habit built on objects and cmdlets stops working. This guide explains what Bash is, how to run it from a Windows PC, and where it still beats the shell you already know.
TL;DR
- Bash is a shell: a program that reads commands and runs them. The terminal is only the window around it.
- It is the default shell on many Linux distributions and the one WSL, Git for Windows and Azure Cloud Shell give you on Windows.
- A Bash script is a text file with a
#!first line, made executable and run like a program. - Exit codes and three
setoptions decide whether a script fails loudly or quietly keeps going. - cron schedules scripts with five time fields. Use PowerShell for Windows objects and Bash for Linux text and files.
What Bash Is
Bash is the shell, or command language interpreter, for the GNU operating system. The name is a pun on Stephen Bourne, who wrote the Unix shell Bash descends from: it stands for Bourne-Again SHell. The GNU manual describes it as largely compatible with the older sh and as borrowing features from the Korn shell and the C shell. The current manual covers Bash 5.3 and is dated 18 May 2025.
Three words get mixed up, so pin them down once. The terminal is the window that shows text. The shell is the program inside it that reads what you type and starts other programs. Bash is one shell. PowerShell and cmd are others.
Bash works two ways. Interactive, you type a command and read the result. Non-interactive, you put commands in a file and Bash runs them top to bottom. The second mode is what people mean by Bash scripting, and the file is a Bash script.
Why a Windows Admin Meets Bash
A lot of what runs a client's infrastructure is not Windows. NAS boxes, firewalls, hypervisors, web servers, containers and cloud shells are Linux underneath, and their automation is written in Bash because it is installed everywhere and needs nothing else. A one-line fix in a vendor knowledge base is usually a Bash line.
You rarely have to leave Windows to use it. Microsoft documents three routes that cover almost every case, and the choice follows the job.
| Route | What it is | Reach for it when |
|---|---|---|
| WSL | A real Linux distribution on Windows, installed with wsl --install, which sets up Ubuntu by default | You need the full Linux toolset, packages and scripts that expect Linux |
| Git Bash | The Bash emulation that ships with Git for Windows | You want grep, ssh and simple scripts with no Linux install |
| Azure Cloud Shell | A browser terminal where you choose Bash or PowerShell | You manage Azure from a machine you cannot install anything on |
WSL needs Windows 10 version 2004 or later, or Windows 11, per Microsoft Learn (updated August 2025). WSL 2 runs the Linux kernel in a lightweight virtual machine. Cloud Shell sessions time out after 20 minutes without interactive activity, and your files persist in a 5 GB file share (Microsoft Learn, August 2026).
Your First Bash Script
A script is a text file. Make one called disk-check.sh:
bash#!/usr/bin/env bash
# Warn when a mount point is nearly full
threshold=85
usage=$(df --output=pcent / | tail -1 | tr -dc '0-9')
if [ "$usage" -ge "$threshold" ]; then
echo "Disk is at ${usage}% on /"
exit 1
fi
echo "Disk OK at ${usage}%"
Each part earns its place. The first line begins with #!, which tells the operating system which interpreter should run the file; the GNU manual explains that the rest of that line names the interpreter and its arguments. Using env finds Bash wherever the system keeps it. A variable is set with no spaces around the = and read with a $. Command substitution, $(...), captures what a command prints. The if test wants spaces inside the brackets, and exit 1 tells whoever called the script that it failed.
Run it in three steps: chmod +x disk-check.sh to mark it executable, then ./disk-check.sh, then echo $? to read the exit code. A loop over several hosts follows the same pattern:
bashfor host in web01 web02 db01; do
ssh "$host" 'df -h /' || echo "$host unreachable"
done
Quote your variables, as in "$host". An unquoted variable that contains a space becomes two words, and that one habit is a common cause of broken scripts. If you keep a cheat sheet of useful PowerShell commands, keep a short one for Bash next to it.
Exit Codes and the Safety Line
Every command finishes with an exit status. By convention zero means success and anything else means failure, and Bash puts the last one in $?. A script that ignores those codes keeps running after a failure, which is how a half-finished backup or a deletion on the wrong path happens quietly.
Three options in the set builtin fix much of it, and the GNU manual documents each one:
-eexits the script when a command fails.-utreats an unset variable as an error. Without it, a typo in a variable name becomes an empty string.-o pipefailmakes a pipeline return the rightmost non-zero status, where the default is the status of the last command only.
Many scripts start with one line that turns all three on:
bashset -euo pipefail
It is a starting point and not a cure. The manual notes that -e has exceptions: it does not trigger for commands inside an if test, in && or || lists, or when a command's status is negated with !. Check the exit status yourself for anything you cannot afford to miss, and send errors to standard error with echo "message" >&2 so logs and pipes stay clean.
The Commands Worth Learning First
You do not need the whole language. A dozen commands cover a large share of admin work, and each has a PowerShell counterpart you already know, which is the quickest way to learn them.
| Bash | What it does | PowerShell counterpart |
|---|---|---|
ls -la | List files, including hidden ones, with details | Get-ChildItem -Force |
cd, pwd | Change and show the current folder | Set-Location, Get-Location |
cat file | Print a file | Get-Content file |
tail -f log | Follow a log as it grows | Get-Content log -Wait -Tail 20 |
grep -i text file | Find lines that match | Select-String text file |
find . -name "*.log" | Search folders for files | Get-ChildItem -Recurse -Filter *.log |
ps aux, kill pid | List and stop processes | Get-Process, Stop-Process |
systemctl status svc | Check and control a service | Get-Service, Restart-Service |
df -h, du -sh * | Disk free space and folder sizes | Get-Volume, Get-ChildItem with sizes |
chmod +x file | Make a file executable | no direct match; permissions use icacls |
curl -I url | Fetch a URL or its headers | Invoke-WebRequest -Method Head |
ssh user@host | Open a remote shell | ssh user@host |
Two habits pay off at once. Chain commands with a pipe, so ps aux | grep nginx lists processes and keeps the lines that mention nginx. And read the manual from the shell: man grep opens the manual page and grep --help prints a short summary.
Scheduling With Cron
cron runs commands on a schedule. It lives in a background process, which is the kind of long-running program covered in our guide to what a daemon is, and you edit your own table with crontab -e. Each line has five time fields followed by the command, per the crontab manual page: minute, hour, day of month, month and day of week. cron checks its entries every minute.
bash# m h dom mon dow command
30 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
0 */6 * * 1-5 /opt/scripts/disk-check.sh
The first line runs at 02:30 every day. The second runs every six hours on weekdays. Two cautions come from the same manual page. A job set inside the hour that daylight saving time skips will never run, and a time that happens twice runs twice, so keep important jobs away from the clock change.
The bigger trap is the environment. cron starts jobs with a minimal one, so a script that works in your terminal can fail from cron because a command is not on the PATH. Use full paths, redirect output to a log, and test with env -i to see what the job sees. If you collect those logs centrally, our guide to log management covers where they should go.
A r/linuxadmin thread from August 2026 shows how far a small Bash loop goes: a script that reads a list of servers from a text file and pings each one, with the top reply pointing out that fping -f does the same job in a single command. Check whether a tool already does the work before you write the loop, and remember that jobs like this are exactly what cron runs.
Five Mistakes That Break Scripts
Failed Bash scripts tend to fail in the same few ways, and the causes are easy to rule out.
- Windows line endings. A script saved with Windows CRLF endings often fails with an error about a bad interpreter or a stray carriage return. Convert it with
dos2unix, or set your editor and Git to save Unix line endings for.shfiles. - Missing permission.
./script.shneeds the executable bit.bash script.shworks without it, which is a quick way to tell the two causes apart. - Unquoted variables.
rm -rf $dir/*with an empty$diris the classic disaster. Quote it, and letset -ucatch the empty one. - sh instead of bash. Features such as
[[ ... ]]and arrays exist in Bash and not in plainsh. A#!/bin/shfirst line, or runningsh script.sh, hides them. - An interactive habit. Aliases and your login environment are not there for cron,
ssh host commandor a CI runner. Use full paths and set what the script needs.
Bash vs PowerShell
The real difference is what flows through a pipe. Bash passes plain text between commands, so you learn grep, awk, sed and cut to pick fields out of lines. PowerShell passes .NET objects, so you select properties by name and never parse a line. Neither is better, and each is stronger on its own ground.
| Bash | PowerShell | |
|---|---|---|
| Pipeline carries | Text | Objects |
| Strongest at | Files, processes, packages, Linux services | Windows, Active Directory, Microsoft 365, the registry |
| Where it is installed | Almost every Linux and Unix system, macOS | Windows by default, plus Linux and macOS |
| Remote use | ssh | WinRM or SSH |
| Weak spot | Quoting, and Windows internals | Linux packaging, and speed on text |
Choose by target. A Windows server, a user in Active Directory or a Microsoft 365 tenant is PowerShell work. A Linux box, a container or a vendor appliance is Bash work. When both are in the same estate, running Bash through WSL on the admin PC and PowerShell for the Windows side works well, and WinRM and remote PowerShell covers the Windows half.
Microsoft's own explainer covers the same three shells in a few minutes:
A thread in r/PowerShell from August 2026 asks how to organize a growing folder of PowerShell, Bash and Python scripts that run on a schedule. The replies agree on the basics for a mixed estate: keep the scripts in a Git repository with a README, turn repeated code into functions or modules, and publish modules to an internal feed so Install-Module and Update-Module keep machines current.
OpenFrame can run a script across a client's devices and collect the output, which is the same idea as a loop over hosts without the loop.
The Short Version
Bash is the shell behind a lot of Linux automation. You can run it from Windows through WSL, Git Bash or Azure Cloud Shell. A script is a file with a #! line, made executable. Start it with set -euo pipefail, quote your variables, and test jobs under cron with full paths. Use Bash where the target is Linux and PowerShell where it is Windows. For the Windows side, our guide to PowerShell execution policy is the next stop.
FAQ
What is Bash used for?
Bash runs commands interactively and automates them in scripts. Typical jobs are checking disk space, moving and renaming files, restarting services, deploying code, collecting logs and scheduling tasks with cron on Linux and Unix systems.
What does Bash stand for?
Bourne-Again SHell. The name plays on Stephen Bourne, who wrote the Unix shell that Bash descends from, and it comes from the GNU Project's description of the shell.
Is Bash a programming language?
It is a command language with variables, conditions, loops and functions, so you can write real programs in it. It works well for gluing other commands together, and it is a poor fit for heavy data work, where Python or PowerShell usually serves better.
Can I run Bash on Windows 11?
Yes. Install WSL with wsl --install for a full Linux distribution, use Git Bash for a lightweight emulation, or open Azure Cloud Shell in a browser and choose Bash.
What is the difference between Bash and a shell script?
Bash is the interpreter. A shell script is a file of commands that Bash, or another shell, runs. A script that begins with #!/usr/bin/env bash is a Bash script.
Content Marketing Lead
Ohayo! I run content, SEO, social, and community at Flamingo. Before IT, I worked as a correspondent for Ukraine's Public Broadcasting Company and have a Master's in journalism.
