使用新变量存储命令的标准输出?

在我的剧本中,我想创建一个变量来保存外部命令的输出。之后,我想在两个模板中使用这个变量。

以下是剧本的相关部分:

  tasks:
- name: Create variable from command
command: "echo Hello"
register: command_output
- debug: msg="{{command_output.stdout}}"


- name: Copy test service
template: src=../templates/test.service.j2 dest=/tmp/test.service
- name: Enable test service
shell: systemctl enable /tmp/test.service
- name: Start test service
shell: systemctl start test.service

这是我的模板:

[Unit]
Description=MyApp
After=docker.service
Requires=docker.service


[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox1
ExecStartPre=-/usr/bin/docker rm busybox1
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo {{ string_to_echo }}; sleep 1; done"


[Install]
WantedBy=multi-user.target

(Notice the {{ string_to_echo }})

所以我基本上在寻找一种方法,将 command_output.stdout的内容(在第一个任务期间生成/检索)存储在一个新的变量 string_to_echo中。
之后我想在多个模板中使用的变量。

我想我可以只使用 {{command_output.stdout}}在我的模板,但我想摆脱的 .stdout的可读性。

268887 次浏览

你必须:

- set_fact:
string_to_echo: "\{\{ command_output.stdout }}"

没必要设定事实。

    - shell: cat "hello"
register: cat_contents


- shell: echo "I cat hello"
when: cat_contents.stdout == "hello"

我在 Ansible 是个新手,但我建议下一个解决方案:

剧本

...
vars:
command_output_full:
stdout: will be overriden below
command_output: \{\{ command_output_full.stdout }}
...
...
...
tasks:
- name: Create variable from command
command: "echo Hello"
register: command_output_full
- debug: msg="\{\{ command_output }}"

它应该可以工作(对我来说也可以) ,因为 Anble 使用惰性计算。但它似乎在启动前检查有效性,所以我必须在 vars 中定义 command_output_full.stdout

而且,当然,如果在 vars部分有太多这样的变量,它将看起来很丑陋。

如果你想存储一个复杂的命令来比较文本结果,例如比较操作系统的版本,也许这个可以帮助你:

tasks:
- shell: echo $(cat /etc/issue | awk {'print $7'})
register: echo_content


- shell: echo "It works"
when: echo_content.stdout == "12"
register: out
- debug: var=out.stdout_lines

对@udondan 的回答稍作修改。我喜欢在 set_fact中重用已注册的变量名,以帮助尽量减少混乱。

因此,如果要使用变量 psk进行注册,我将在创建 set_fact时使用相同的变量名。

例子

- name: generate PSK
shell: openssl rand -base64 48
register: psk
delegate_to: 127.0.0.1
run_once: true


- set_fact:
psk=\{\{ psk.stdout }}


- debug: var=psk
run_once: true

Then when I run it:

$ ansible-playbook -i inventory setup_ipsec.yml


PLAY                                                                                                                                                                                [all] *************************************************************************************************************************************************************************


TASK [Gathering                                                                                                                                                                     Facts] *************************************************************************************************************************************************************
ok: [hostc.mydom.com]
ok: [hostb.mydom.com]
ok: [hosta.mydom.com]


TASK [libreswan : generate                                                                                                                                                          PSK] ****************************************************************************************************************************************************
changed: [hosta.mydom.com -> 127.0.0.1]


TASK [libreswan :                                                                                                                                                                   set_fact] ********************************************************************************************************************************************************
ok: [hosta.mydom.com]
ok: [hostb.mydom.com]
ok: [hostc.mydom.com]


TASK [libreswan :                                                                                                                                                                   debug] ***********************************************************************************************************************************************************
ok: [hosta.mydom.com] => {
"psk": "6Tx/4CPBa1xmQ9A6yKi7ifONgoYAXfbo50WXPc1kGcird7u/pVso/vQtz+WdBIvo"
}


PLAY                                                                                                                                                                                RECAP *************************************************************************************************************************************************************************
hosta.mydom.com    : ok=4    changed=1    unreachable=0    failed=0
hostb.mydom.com    : ok=2    changed=0    unreachable=0    failed=0
hostc.mydom.com    : ok=2    changed=0    unreachable=0    failed=0

If you want to go further and extract the exact information you want from the Playbook results, use JSON query language like jmespath, an example:

  - name: Sample Playbook
// Fill up your task
no_log: True
register: example_output


- name: Json Query
set_fact:
query_result:
example_output:"\{\{ example_output | json_query('results[*].name') }}"