Read the arguments passed to your script with $1, $2, $@, and $#. Use special variables like $0, $?, and $$, and shift through a list of positional parameters.
Why: when a script is run as ./deploy.sh web prod, the words after the script name become positional parameters. $1 is the first, $2 the second, and so on. $0 is the script's own name.
#!/usr/bin/env bash
# Run as: ./deploy.sh web prod
echo "Script name: $0" # ./deploy.sh
echo "First arg: $1" # web
echo "Second arg: $2" # prodWhy: $# is how many arguments were passed — use it to check the script was called correctly. "$@" expands to every argument, each safely quoted as its own word; that is what you almost always want when forwarding arguments. Note: "$*" joins them into one string instead — rarely what you mean.
#!/usr/bin/env bash
echo "Got $# arguments" # the count
# Loop over each argument, space-safe
for arg in "$@"; do
echo "arg: $arg"
doneWhy: a script that needs an argument should fail loudly when it is missing, not run with an empty value. Check $# and exit with a non-zero code and a usage message. Note: >&2 sends the message to standard error — covered in the redirection lesson.
#!/usr/bin/env bash
if [ "$#" -lt 1 ]; then
echo "Usage: $0 <environment>" >&2
exit 1
fi
echo "Deploying to $1"Why: shift drops $1 and renumbers the rest ($2 becomes $1, and so on). It lets you peel off a leading argument — like a command name — and then process whatever remains.
#!/usr/bin/env bash
# Run as: ./tool.sh add file1 file2 file3
action="$1" # add
shift # drop it; the files are now "$@"
echo "Action: $action"
for f in "$@"; do
echo "processing $f"
doneNote: $? is the exit code of the last command (0 means success) — central to the error-handling lesson. $$ is the current script's process ID, useful for unique temp file names. $! is the PID of the last background command.
#!/usr/bin/env bash
ls /tmp > /dev/null
echo "ls exit code: $?" # 0 if it succeeded
tmpfile="/tmp/work.$$" # unique per run via the PID
echo "using temp file $tmpfile"