Shell Scripting Basics
Turn a sequence of commands into a reusable script: variables, conditionals, loops, and functions.
On this page10 sections
Every command you've typed so far in this course, you typed by hand, one at a time. A shell script is just those same commands saved in a file so you - or a server, or a scheduled job - can run the whole sequence with one word. Scripting is what turns "things I can do" into "things that happen automatically."
The shebang
The first line of a script tells the system which interpreter should run it. By convention it starts with #! (pronounced "shebang") followed by the interpreter's path:
#!/bin/bash
echo "hello, world"
Without a shebang, running the file falls back to whatever shell happens to be interpreting it, which isn't guaranteed to match what you wrote the script for. Always include one.
Making a script runnable
A script needs execute permission before you can run it directly - you covered chmod in the permissions lesson:
chmod +x greet.sh
./greet.sh # the ./ means "run the file in THIS directory", not a PATH lookup
Without execute permission (or the ./), you can still run a script by naming the interpreter explicitly: bash greet.sh.
Variables
Scripts use the same NAME=value syntax you already know from export, usually without export unless the variable needs to be visible to programs the script calls:
name="learner"
echo "hello, $name"
No spaces around = - name = "learner" is a syntax error, not an assignment.
Arguments and special variables
When a script runs, the shell hands it a set of built-in variables:
| Variable | Meaning |
|---|---|
$1, $2, ... | The first, second, ... argument passed to the script |
$@ | All arguments, as separate words |
$# | The number of arguments |
$0 | The script's own name |
$? | The exit status of the last command (0 means success) |
#!/bin/bash
echo "script name: $0"
echo "first arg: $1"
echo "arg count: $#"
Conditionals
if [ "$1" = "prod" ]; then
echo "deploying to production"
elif [ "$1" = "staging" ]; then
echo "deploying to staging"
else
echo "usage: $0 <prod|staging>"
fi
[ ... ] is itself a command (a synonym for test) - that's why the spaces around the brackets matter. Modern bash also supports [[ ... ]], which is more forgiving and adds pattern matching.
Loops
for f in *.log; do
echo "found: $f"
done
count=0
while [ $count -lt 3 ]; do
echo "count is $count"
count=$((count + 1))
done
Functions
greet() {
echo "hello, $1"
}
greet "world"
Comments and exit codes
Lines starting with # are comments, except the very first #! line, which is special. A script's own exit code - what $? will hold for whoever calls it - is set with exit:
if [ ! -f "config.yml" ]; then
echo "missing config.yml"
exit 1
fi
exit 0
By convention, 0 means success and any non-zero number means failure. This is exactly how the && and || chains you learned earlier, and every CI pipeline, decide whether a step "worked."
The practice terminal is a small teaching REPL, not a full shell interpreter - it does not execute
if,for,while, or./script.sh. Use it to build and inspect script files; run them for real in an actual Linux terminal or WSL to see the control flow in action.
Try it
echo '#!/bin/bash' > greet.sh
echo 'echo "hello, world"' >> greet.sh
cat greet.sh
chmod +x greet.sh
cat shows you exactly what you wrote: a shebang line and an echo. On a real system, ./greet.sh would now print the greeting.
Further reading
- "Learning the bash Shell" by Cameron Newham (O'Reilly) - a complete, approachable guide to scripting in bash, from variables through functions.
- "The Linux Command Line" by William Shotts (No Starch Press) - Part III is entirely dedicated to writing shell scripts, building up from this exact material to a full program.
Challenge
Create a script file greet.sh whose first line is #!/bin/bash and whose second line is echo "hello, world" (one echo with >, one with >>), then make it executable. Do all three steps in one line joined with &&.
Want to experiment first? Try things in the practice terminal (opens in a new tab), then enter the command that solves the task here.
Quiz
Lock in the concepts. Score at least 80% to mark the lesson complete.
Done with this one?
Skipped the challenge? You can mark the lesson complete by hand.