【问题标题】:Ansible: Store command's stdout in new variable?Ansible:将命令的标准输出存储在新变量中?
【发布时间】:2016-07-03 18:10:08
【问题描述】:

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

以下是剧本的相关部分:

  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

(注意{{ string_to_echo }}

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

我想我可以在我的模板中使用{{command_output.stdout}},但为了便于阅读,我想去掉那个.stdout

【问题讨论】:

    标签: ansible ansible-playbook


    【解决方案1】:

    你必须store the content as a fact:

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

    【讨论】:

      【解决方案2】:

      没有必要设定一个事实。

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

      【讨论】:

      • 这很有帮助,但这确实意味着以后在使用该变量时,您也必须记住使用.stdout
      • 当然没有必要设置一个事实。但这正是 OP 所要求的。这如何为问题提供任何答案?
      • 是否可以将远程命令输出即时打印到主机?我的 shell 命令运行了较长时间,我想在控制台输出仍在运行时发回它。
      【解决方案3】:

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

      playbook.yml

      ...
      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 }}"
      

      它应该可以工作(并且对我有用),因为 Ansible 使用惰性求值。但它似乎在发布前检查有效性,所以我必须在 vars 中定义command_output_full.stdout

      当然,如果vars 部分中这样的变量太多,它看起来会很丑。

      【讨论】:

        【解决方案4】:

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

        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
        

        【讨论】:

          【解决方案5】:

          在@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
          

          然后当我运行它时:

          $ 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
          

          【讨论】:

            【解决方案6】:

            如果您想更进一步并从 Playbook 结果中提取所需的确切信息,请使用 JSON 查询语言,例如 jmespath,例如:

              - 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') }}"
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-03-10
              • 1970-01-01
              • 1970-01-01
              • 2022-08-10
              • 1970-01-01
              • 1970-01-01
              • 2015-08-07
              相关资源
              最近更新 更多