1

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:

custom_options=${columns[2]}

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:

#!/bin/bash
set -x
touch "as is"
command='-name "as is"'
find . $command -type f
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • This is [Bash FAQ 50](http://mywiki.wooledge.org/BashFAQ/050) – glenn jackman Mar 03 '16 at 21:03
  • Bash isn't adding any quotes. That's its way of printing out the command when it would be visually ambiguous — bash is saying that `"client=yes fast=no"` is one argument, starting and ending with double quotes. – Gilles 'SO- stop being evil' Mar 03 '16 at 23:38
  • 1
    See our reference question: [Why does my shell script choke on whitespace or other special characters?](http://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters) – Gilles 'SO- stop being evil' Mar 03 '16 at 23:38

1 Answers1

2

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.