11

本质上,我希望能够使用 ansible 在 Linux 中处理“通配符文件名”。本质上,这意味着使用 ls 命令,文件名的一部分后跟一个“*”,以便它只列出某些文件。

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

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

我完全不确定如何在 ansible 中正确实现/操作数组,因此以下代码是我“尝试”完成的示例。显然,如果返回多个文件名,它将无法按预期运行,这就是我在此主题上寻求帮助的原因:

- 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 格式有点混乱,但如果它是固定的,这个“将”正常运行,它不会给我我正在寻找的输出。因此,如果有 50 个文件,我希望 ansible 能够全部操作它们,和/或能够全部删除它们......等等等等。

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

4

3 回答 3

16

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

要迭代元素,请使用:

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

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

于 2017-02-16T23:29:22.427 回答
0

你可以尝试如下。

- name: Run command to cat each file and then capture that output.
   shell: cat {{ item.stdout_lines }}
   register: annoying_words
   with_items:
    - "{{ annoying.results }}"
于 2019-05-30T10:21:19.747 回答
0

annoying.stdout_lines已经是一个列表。

来自stdout_lines的文档

当 stdout 返回时,Ansible 总是提供一个字符串列表,每个字符串包含原始输出中的每行一个项目。

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

    ..
      register: annoying
    - set_fact:
        varName: "{{annoying.stdout_lines}}"
    # print first element on the list
    - debug: msg="{{varName | first}}"
于 2019-06-27T15:02:01.250 回答