A Bash script is not a different kind of magic command. It is a text file that gives the shell a sequence of commands, values, and decisions to execute in a repeatable order.
A Bash script is a plain-text file containing commands Bash can interpret. A shebang can select the interpreter when the file is executed directly. Variables hold values, positional parameters receive arguments, conditionals choose a path, loops repeat work, and exit statuses tell the caller whether the script succeeded.
You can run a script explicitly with bash script.sh, or make
it executable and run it as ./script.sh.
- What You’ll Learn
- What Is a Bash Script?
- Build Your First Linux Shell Script
- Run it through Bash
- Run it as an executable file
- Variables, Arguments, and Quoting
- How Bash Scripts Make Decisions
- Choose [[ ... ]] deliberately
- Repeat Work with a Loop
- Mini Lab: Create a Safe Path Inspector
- Common Bash Scripting Mistakes
- Knowledge Check
- Official References
What You’ll Learn
- What Bash actually does with a script file.
- How to create and run a first script safely.
- How variables and script arguments differ.
- How quoting protects values containing spaces.
- How conditions and loops control execution.
- How a script reports success or failure.
What Is a Bash Script?
A Bash script is a file containing shell syntax. Bash reads that file, performs expansions, runs commands, and uses their exit statuses to decide which branches or loops should continue.
The file does not become reliable merely because its commands work once in an interactive terminal. A useful script makes its inputs, interpreter, failure behavior, and observable result explicit.
This connects several earlier lessons. The shell interprets the commands . Variables provide values . Standard streams carry input and output . Exit codes drive decisions . A script puts those pieces into a reusable file.
Once a script is reliable, the next step is learning how to run it automatically. The Linux cron jobs guide explains crontab schedules, execution environments, output handling, and common failures.
Build Your First Linux Shell Script
Create a file named hello.sh with this content:
#!/usr/bin/env bash
name=${1:-operator}
printf 'Hello, %s\n' "$name"
The first line is the shebang. When the executable file is
launched directly, the operating system uses it to locate the interpreter.
/usr/bin/env bash searches the current PATH for
Bash. That is convenient for a learning script and many user-managed
environments.
Administrative scripts may instead use #!/bin/bash when that
exact path is guaranteed and choosing the system interpreter deliberately
matters. The best choice depends on where the script will run.
Run it through Bash
bash hello.sh
bash hello.sh Dana
In this form, Bash is started explicitly and receives the file as input. The file itself does not need execute permission.
Run it as an executable file
chmod u+x hello.sh
./hello.sh Dana
chmod u+x gives the file’s owner execute permission. The
./ prefix tells the shell to use the file in the current
directory. The shebang then selects Bash.
bash hello.sh explicitly
chooses Bash. ./hello.sh relies on execute permission and the
interpreter declared by the shebang.
Variables, Arguments, and Quoting
A variable gives a name to a value inside the script. Bash assignments do not allow spaces around the equals sign:
service_name=web
printf 'Checking %s\n' "$service_name"
Arguments arrive as positional parameters. $1 is the first
argument, $2 is the second, $# is the number of
arguments, and "$@" expands to all arguments while preserving
each one as a separate value.
| Expression | Meaning | Typical use |
|---|---|---|
$0 |
Name used to invoke the script | Usage and error messages |
$1 |
First positional argument | A filename, mode, or other input |
$# |
Number of positional arguments | Validate required input |
"$@" |
All arguments, preserved as separate words | Loop safely over supplied values |
$? |
Status of the latest foreground pipeline | Capture success or failure immediately |
Double quotes are essential when a value may contain spaces or wildcard characters. Compare the intent:
path="Project Files/report.txt"
printf '%s\n' "$path"
With "$path", Bash passes one argument. Without quotes, word
splitting and filename expansion can change the number or meaning of
arguments.
report.txt may fail for
monthly report.txt. Quoting should reflect the data model, not
the sample filename.
How Bash Scripts Make Decisions
An if statement runs commands as its condition. If that
condition returns status 0, Bash executes the
then branch. Otherwise, it can execute else.
file=$1
if [[ -r "$file" ]]; then
printf '%s is readable\n' "$file"
else
printf '%s is missing or unreadable\n' "$file" >&2
exit 1
fi
[[ -r "$file" ]] is a Bash conditional expression that succeeds
when the path exists and is readable in the current context. The error
message is redirected to standard error, and exit 1 reports
failure to the caller.
Choose [[ ... ]] deliberately
[[ ... ]] is Bash syntax. It offers convenient conditional
behavior, but a script using it should identify Bash as its interpreter.
Portable sh scripts use different constraints and commonly use
test or [ ... ].
Repeat Work with a Loop
A for loop can process each argument without duplicating
commands:
for path in "$@"; do
printf 'Inspecting: %s\n' "$path"
done
Quoting "$@" preserves each original argument, including
filenames containing spaces. Bash assigns one argument at a time to
path and runs the loop body for it.
| Construct | Purpose | Mental model |
|---|---|---|
if |
Choose a branch from command status | Run this when the condition succeeds |
for |
Process a known list of values | Run once for each item |
while |
Repeat while a condition succeeds | Check, run, then check again |
case |
Match one value against patterns | Choose among named modes or shapes |
function |
Group reusable commands | Give one operation a name |
Mini Lab: Create a Safe Path Inspector
This lab works inside a temporary directory and only reads the sample paths it creates.
SA_SCRIPT_LAB=$(mktemp -d)
cd "$SA_SCRIPT_LAB" || exit 1
printf 'Workspace: %s\n' "$SA_SCRIPT_LAB"
cat > inspect-paths.sh <<'EOF'
#!/usr/bin/env bash
if (( $# == 0 )); then
printf 'Usage: %s PATH...\n' "$0" >&2
exit 2
fi
for path in "$@"; do
if [[ -f "$path" ]]; then
bytes=$(wc -c < "$path")
printf 'File: %s (%s bytes)\n' "$path" "$bytes"
elif [[ -d "$path" ]]; then
printf 'Directory: %s\n' "$path"
else
printf 'Unavailable: %s\n' "$path" >&2
fi
done
EOF
The quoted 'EOF' delimiter prevents the current
interactive shell from expanding variables while it creates the file.
bash -n inspect-paths.sh
No output normally means Bash found no syntax error. This does not prove that the script’s logic is correct, but it catches structural mistakes.
printf 'alpha\n' > "sample file.txt"
mkdir sample-directory
chmod u+x inspect-paths.sh
./inspect-paths.sh "sample file.txt" sample-directory missing
Observe that the filename containing a space remains one argument. The missing path produces an error message without stopping inspection of the other inputs.
printf 'Removing: %s\n' "$SA_SCRIPT_LAB"
cd /tmp || exit 1
rm -r -- "$SA_SCRIPT_LAB"
unset SA_SCRIPT_LAB
Common Bash Scripting Mistakes
sh script.sh, or
it uses Bash syntax while declaring a different shell.
$1 exists and fails later with a confusing
message.
Knowledge Check
1. What is a Bash script?
2. What does the shebang do?
3. Why does bash script.sh work without execute permission?
4. Why should "$@" usually be quoted?
5. What makes an if condition true in Bash?
6. What does bash -n script.sh verify?
A Bash script is a repeatable conversation with the shell. Arguments provide input, variables hold values, quoting preserves their boundaries, commands perform work, conditions and loops control the path, streams carry messages, and the final exit status reports the outcome.
Start with a small script whose behavior you can observe. Validate its input, quote data values, check the commands that matter, and make success or failure clear to both people and calling programs.








