Script foundations
Read positional arguments
Accept a required path argument, show usage, and distinguish the script name from user values.
10 minute lesson
When you run ./check-dir /var/www, Bash stores the script name in $0 and arguments in $1, $2, and so on. $# reports how many arguments were supplied. These are the positional parameters, and they are how a script receives input without prompting anyone.
Require an argument
A script that needs input should check for it up front and explain itself when the caller gets it wrong. Create check-dir:
#!/usr/bin/env bash
if (( $# != 1 )); then
printf 'usage: %s DIRECTORY\n' "$0" >&2
exit 2
fi
directory=$1
printf 'checking %s\n' "$directory"
(( ... )) is arithmetic evaluation, the natural way to compare numbers like $#. The usage message goes to standard error with >&2, not standard output — error text must never mix with real output that another program might consume. Status 2 is the conventional “you called me wrong” code; grep and many other tools use it the same way.
Copying $1 into a named variable is a small kindness to future readers. Twenty lines down, "$directory" explains itself; "$1" doesn’t.
Verify all three cases
Run it with zero, one, and two arguments:
./check-dir
# usage: ./check-dir DIRECTORY
./check-dir /var/www
# checking /var/www
./check-dir /var/www /tmp
# usage: ./check-dir DIRECTORY
Check the status too: echo $? prints 2 after the invalid calls and 0 after the good one. Invalid usage should print to standard error and return status 2 every time, because schedulers and other scripts act on the number, not the text.
Count is not meaning
The realistic mistake is stopping here. One argument can still name a missing or unsafe path:
if [[ ! -d $directory ]]; then
printf '%s is not a directory\n' "$directory" >&2
exit 1
fi
Validate meaning after count. A script that accepts any string as its “log directory” and marches on will fail later, somewhere far less obvious than line three.
One more parameter worth knowing now: "$@" expands to all arguments, each preserved as its own word. We put it to work in the lesson on loops.
Lesson completed