问题
I want to store multiple arguments in a variable as a list.
vars:
my_args:
- --verbose
- --quiet
- --verify
Then pass the list as quoted arguments to a command. The most obvious join
filter doesn't work as I expected. It produces a single word containing all list elements as opposed to one word per list element:
tasks:
- command: printf '%s\n' "{{ my_args | join(' ') }}"
...
changed: [localhost] => {
"changed": true,
"cmd": [
"printf",
"%s\\n",
" --quiet --verbose --verify "
],
STDOUT:
--quiet --verbose --verify
How to pass them to a command?
回答1:
To pass a list elements as arguments to a module use either map('quote') | join(' ')
filters or the for
loop:
tasks:
- name: Pass a list as arguments to a command using filters
command: executable {{ my_args | map('quote') | join(' ') }}
- name: Pass a list as arguments to a command using for loop
command: executable {% for arg in my_args %} "{{ arg }}" {% endfor %}
Do not use quotes with filter, but do use them with a loop. Although being slightly longer, the for
loop gives more possibilities of shaping the output. For example prefixing or suffixing the list item like "prefix {{ item }} suffix"
, or applying filters to the item or even selectively processing items using loop.*
variables.
The example in question would be:
tasks:
- command: printf '%s\n' {{ my_args | map('quote') | join(' ') }}
- command: printf '%s\n' {% for arg in my_args %} "{{ arg }}" {% endfor %}
...
changed: [localhost] => {
"changed": true,
"cmd": [
"printf",
"%s\\n",
"--quiet",
"--verbose",
"--verify"
],
STDOUT:
--quiet
--verbose
--verify
List elements are not limited to simple strings and can contain some logic:
vars:
my_args:
- --dir={{ my_dir }}
- {% if my_option is defined %} --option={{ my_option }} {% endif %}
来源:https://stackoverflow.com/questions/49799595/ansible-pass-command-arguments-as-a-list