Execute a command stored into a $variable

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.

2

3 Answers

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

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

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.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like