Bash – Iterate over multiple parameters with spaces in bash script

bashscriptingshell-script

I have a bash script for my RaspberryPi (running Raspbian) that is supposed to take multiple file names as parameter(s) and play one after the other (using omxplayer). The basic structure is this:

#!/bin/bash
for f in ${*}
do
  echo "${f}";
done;

Now I have problems when the input filenames contain spaces; in particular, the behaviour seems to be inconsistent. Assume we have two files test a b and test d e in the same directory. Running above script with different parameters yields this:

$ ./test test\ a\ b
test
a
b
$ ./test "test a b"
test
a
b
$ ./test test\ a*
test
a
b
$ ./test "test a*"
test
a*

But, curiously:

./test "test*"
test a b
test d e

Obviously, only this last variant provides the intended output. It is cumbersome to use, however, especially if you want to watch a single file (tab-completion will fill in the whole name) or if one of the folder names in the file's path contains spaces.

What can I do differently in the shellscript so that it will always behave as intended? In particular, both of

$./test test*
$./test test\ a\ b test\ d\ e

should produce the same output

test a b
test d e    

so the script can be used easily using normal tab-completion.

Best Answer

Use "$@" instead of ${*} (see Special Parameters in the manual)

for f in "$@"; do 
    echo make sure you quote your "$variables" everywhere in the loop

There's a shorthand (and more portable) for this:

for f do ...

for f; do would also work in some shells but is not standard.

Related Question