Ubuntu – Execute a command stored into a $variable

bashcommand linescripts

I made a script where I wrote:

COMMAND="/usr/bin/exiftool $PATH_NAME"
.... code ....
$COMMAND

The variable $PATH_NAME is assigned dynamically inside a while loop.
The command works fine until it encounters files with spaces (for example PATH_NAME="Add Driver.png").
The console output is:

File not found: ./Add
File not found: driver.png

The command should be:

/usr/bin/exiftool ./Add driver.png

I think the problem is given by the spaces in the $PATH_NAME. I tried also to execute directly the command:

eval "/usr/bin/exiftool $PATH_NAME"

But same output error. Any idea to solve the problem? thanks.

Best Answer

Instead of using simple strings, build your command using arrays. Arrays provide a convenient interface: If a is an array, then "${a[@]}" (note the quotes) expands into each element of a, without additional field splitting or globbing (so spaces, and things like wildcards, should remain intact).

Example:

$ a=(printf "|%s|\n" "foo   bar" "*")
$ echo ${a[@]}
printf |%s|\n foo bar bin boot dev etc home lib lib64 lost+found mnt opt proc root run sbin srv sys tmp usr var

Note how the * was expanded, and how the extra spaces between foo and bar were lost. But with the "${a[@]}", these are preserved:

$ echo "${a[@]}"
printf |%s|\n foo   bar *

This is ideal for building commands. Now, you can do:

$ "${a[@]}"
|foo   bar|
|*|

See? The arguments were retained perfectly.

So, do:

COMMAND=(/usr/bin/exiftool "$PATH_NAME")
"${COMMAND[@]}"
Related Question