4

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.

5

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[@]}"
1

For more detailed explanations about how Bash interprets spaces, I recommend to read this: Bash variables and command substitution

Clean solution

Expanding a variable can lead to unexpected and sometimes catastrophic results if the variable contains special characters:

user@host:~$ do_something $some_variable

Expanding a variable within double-quotes can prevent such problems:

user@host:~$ do_something "$some_variable"

Explanation

The case encountered here is described at the end of the post:

The dangers of unquoted variables

In an ideal world, everyone would keep their string values short and without space/newline, or any other special characters.

[...]

But when people start adding special characters to filenames, such as spaces, expanding variables, without the use of double quotes, can be dangerous.

[...]

So the main takeaway here is: double-quote your variable references whenever possible.

0

glenn jackman's point is well taken. But, to solve your immediate use case, how about backticks? Like so:

`echo $COMMAND`

For example, this works:

COMMAND='ls /'
`echo $COMMAND`
  • 1
    -1 Why `echo $COMMAND` and not just $COMMAND? They have the same effect (except for some corner cases of which the echo variant has more). – David Foerster Apr 26 '16 at 21:01

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.