Looping Over Arguments Passed to a Script
Problem
You want to take some set of actions for a given list of arguments. You could
write your shell script to do that for one argument and use $1
to reference the parameter. But what if
you’d like to do this for a whole bunch of files? You would like to be
able to invoke your script like this:
actall *.txt
knowing that the shell will pattern match and build a list of
filenames that match the *.txt
pattern (any filename ending with .txt
).
Solution
Use the shell special variable $* to refer to all of your arguments, and use
that in a for
loop like
this:
#!/usr/bin/env bash # cookbook filename: chmod_all.1 # # change permissions on a bunch of files # for FN in $* do echo changing $FN chmod 0750 $FN done
Discussion
The variable $FN
is our choice;
we could have used any shell variable name we wanted there. The $*
refers to all the arguments supplied on the command line. For example,
if the user types:
$ ./actall abc.txt another.txt allmynotes.txt
the script will be invoked with $1
equal to abc.txt and
$2
equal to
another.txt and $3
equal to
allmynotes.txt, but $* will be equal to the entire
list. In other words, after the shell has substituted the list for $* in
the for
statement, it will be as if
the script had read:
for FN in abc.txt another.txt allmynotes.txt do echo changing $FN chmod 0750 $FN done
The for
loop will take one
value at a time from the list, assign it to the variable $FN
and proceed through the list of statements between the do and the ...
Get bash Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.