如何将命令输出存储到 Ansible 中的数组中?

How to store command output into array in Ansible?

本质上,我希望能够使用 ansible 处理 Linux 中的 "wildcard filenames"。本质上,这意味着使用 ls 命令加上文件名的一部分后跟一个“*”,这样它将只列出某些文件。

但是,我无法将输出正确存储在变量中,因为可能会返回多个文件名。因此,我希望能够存储这些结果,而不管在一项任务期间数组中可能有多少。然后我希望能够在以后的任务中从数组中检索所有结果。此外,由于我不知道可能会返回多少文件,因此我无法为每个文件名执行任务,而数组更有意义。

这背后的原因是随机存储位置中的文件经常更改,但它们总是具有相同的前半部分。他们名字的后半部分是随机的,我根本不想将其硬编码到 ansible 中。

我完全不确定如何在 ansible 中正确地 implement/manipulate 一个数组,所以下面的代码是我要 "trying" 完成的示例。显然,如果返回多个文件名,它将无法按预期运行,这就是我寻求有关此主题的帮助的原因:

- hosts: <randomservername>
  remote_user: remoteguy
  become: yes
  become_method: sudo
  vars:
    aaaa: b
  tasks:

 - name: Copy over all random file contents from directory on control node to target clients.  This is to show how to manipulate wildcard filenames.
    copy:
      src: /opt/home/remoteguy/copyable-files/testdir/
      dest: /tmp/
      owner: remoteguy
      mode: u=rwx,g=r,o=r
    ignore_errors: yes

  - name: Determine the current filenames and store in variable for later use, obviously for this exercise we know part of the filenames.
    shell: "ls {{item}}"
    changed_when: false
    register: annoying
    with_items: [/tmp/this-name-is-annoying*, /tmp/this-name-is-also*]

  - name: Run command to cat each file and then capture that output.
    shell: cat {{ annoying }}
    register: annoying_words

  - debug: msg=Here is the output of the two files.  {{annoying_words.stdout_lines }}

  - name: Now, remove the wildcard files from each server to clean up.
    file:
      path: '{{ item }}'
      state: absent
    with_items:
    - "{{ annoying.stdout }}"

我知道 YAML 格式有点混乱,但如果它是固定的,这个 "would" 运行 通常,它不会给我我正在寻找的输出。因此,如果有 50 个文件,我希望 ansible 能够对它们进行操作,and/or 能够将它们全部删除……等等等等。

如果这里有人能让我知道如何在上面的测试代码片段中正确使用数组,那就太棒了!

Ansible 将 shellcommand 操作模块的输出存储在 stdoutstdout_lines 变量中。后者以列表的形式包含单独的标准输出行。

要遍历元素,请使用:

with_items:
  - "{{ annoying.stdout_lines }}"

您应该记住,在某些情况下解析 ls 输出可能会导致问题。

你可以试试下面的方法吗?

- name: Run command to cat each file and then capture that output.
   shell: cat {{ item.stdout_lines }}
   register: annoying_words
   with_items:
    - "{{ annoying.results }}"

annoying.stdout_lines 已经是一个列表。

来自 stdout_lines

的文档

When stdout is returned, Ansible always provides a list of strings, each containing one item per line from the original output.

要将列表分配给另一个变量,请执行以下操作:

    ..
      register: annoying
    - set_fact:
        varName: "{{annoying.stdout_lines}}"
    # print first element on the list
    - debug: msg="{{varName | first}}"