Handling Lists of Parameters with Blanks

Problem

OK, you have quotes around your variable as the previous recipe recommended. But you’re still getting errors. It’s just like the script from the Looping Over Arguments Passed to a Script, but it fails when a file has a blank in its name:

#
for FN in $*
do
    chmod 0750 "$FN"
done

Solution

It has to do with the $* in the script, used in the for loop. For this case we need to use a different but related shell variable, $@. When it is quoted, the resulting list has quotes around each argument separately. The shell script should be written as follows:

#!/usr/bin/env bash
# cookbook filename: chmod_all.2
#
# change permissions on a bunch of files
# with better quoting in case of filenames with blanks
#
for FN in "$@"
do
    chmod 0750 "$FN"
done

Discussion

The parameter $* expands to the list of arguments supplied to the shell script. If you invoke your script like this:

$ myscript these are args

then $* refers to the three arguments these are args. And when used in a for loop, such as:

for FN in $*

then the first time through the loop, $FN is assigned the first word (these) and the second time, the second word (are), etc.

If the arguments are filenames and they are put on the command line by pattern matching, as when you invoke the script this way:

$ myscript *.mp3

then the shell will match all the files in the current directory whose names end with the four characters .mp3, and they will be passed to the script. So consider an example where there are three ...

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.