Linux Labs

Bash: text processing and scripts / Stage 5 of 9

Arguments, quotes and file checks

Not running Starting usually ~20 s
Leave the lesson

Step 2 of 7 · on a machine · 8 min

A script's arguments

A script receives its arguments already split, one word per argument. args.sh will show exactly what it got.

Everything after the script's name on the command line bash splits into arguments — at spaces outside quotes — and hands to the script. Inside the script the arguments sit in positional parameters: $1 is the first, $2 the second, and so on, and $# is how many there are. args.sh prints $# and every argument in angle brackets so you can see where each one begins and ends.

Exercise · look

See what the script receives

In ~/args-lab, run args.sh three times: with the name in quotes, with the same name unquoted, and with no arguments at all.

First, predict

How many arguments will args.sh count in the first command, where "my file.txt" is quoted?

Now start the exercise, run the command and compare your prediction with the output.

Sign in and start The machine is available after signing in

The quotes in the call did their job: args.sh got my file.txt as one argument. From there on, the script is in charge. args.sh walks through its arguments like this: for a in "$@". A for loop runs the commands between do and done for every word in the list after in, and the variable a takes each word in turn. "$@" in double quotes is a special form: all of the script's arguments, each as a separate word, exactly as they were passed.

report.sh writes for f in $@ — without quotes. Then bash expands the arguments and splits them at spaces all over again, like the unquoted $dir in the lesson on scripts. wc -l $f inside the loop repeats the same mistake. For a call with "my file.txt" notes.txt, the difference looks like this:

In the script Words the loop gets
"$@" my file.txt, notes.txt
$@ or $* my, file.txt, notes.txt
"$*" my file.txt notes.txt — one word

Expand one argument as "$1", all of them as "$@", and quote the loop variable too: wc -l "$f".

Ubuntu 24.04
Loading…