I am reading in a file inside my bash script where each line consists of multiple columns like this:

ANSIBLE 'first run' '--diff --extra-vars "client=yes fast=no"'

As you can see, the line consists of three columns, the ones with whitespaces in apostrophes. The third column contain options for a binary to call. As I read in the file, I stored those options to a variable:


This evaluates to

custom_options='--diff --extra-vars "client=yes fast=no"'

Now I want to execute my binary with those options:

ansible-playbook $custom_options site.yml

However this fails, because on execution there were added apostrophes around the inner string:

ansible-playbook --diff --extra-vars '"client=yes fast=no"' site.yml

Does anybody know how to substitute the variable string as-is?

Here is a short script to quickly reproduce the behavior:

set -x
touch "as is"
command='-name "as is"'
find . $command -type f

I found a workaround rather than a solution. I surrounded the whole command with the variable inside an eval expression:

eval "ansible-playbook $custom_options site.yml"

Here the equivalent usage within the example script:

eval "find . $command -type f"

I am no bash guru and I don't know if this workaround has any side effects. Nevertheless I tested following:

  • eval works with pipes: eval "command | tee file"
  • quotes inside eval are possible: eval "command \"${var}\""

However it fit my needs but it feels dirty. Better solutions are welcome.

  • That's the (well, a) right solution. It does mean you need to be very careful about what you put in the custom_options variable. – Gilles Mar 3 '16 at 23:37
  • Of course @Gilles custom_options should be parsed for valid content before usage, to avoid injection points for malicious code. Good hint. – Thomas Steinbach Mar 4 '16 at 17:08

Your Answer

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

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