Ansible 查找模块不会在搜索中排除文件夹

Ansible find module does not exclude folder in the search

提问人:Ashar 提问时间:8/25/2020 最后编辑:Ashar 更新时间:5/28/2022 访问量:6672

问:

这是我的剧本,我试图在目录下找到,但是,我希望从搜索中排除文件夹。test-juli.jar/app/app/Patchbackup

以下是我的剧本:

  tasks:

    - name: Find test home directories under /app
      find:
        paths: /app
        file_type: any
        recurse: yes
        depth: 4
        patterns: 'test-juli.jar'
        excludes: 'log,tmp,.installation,Patchbackup'
      tags: always
      register: tomjarfound

    - debug:
        msg: "ALL LISTED REFINED JARS: {{ item.path }}"
      loop: "{{ tomjarfound.files }}"

当我运行上述内容时,我期望找不到下面,但输出显示尽管被排除在外,但它确实如此。find/app/Patchbackup

输出如下:

TASK [debug] ***********************************************************************************************************************************************************
ok: [10.0.0.11] => (item=/app/apache-test-9.0.10/bin/test-juli.jar) => {
    "msg": "ALL LISTED REFINED JARS: /app/apache-test-9.0.10/bin/test-juli.jar"
}
ok: [10.0.0.11] => (item=/app/Patchbackup/app/apache-test-9.0.10/bin/test-juli.jar) => {
    "msg": "ALL LISTED REFINED JARS: /app/Patchbackup/app/apache-test-9.0.10/bin/test-juli.jar"
}

您能否建议如何从 ansible 的查找中排除该文件夹?/app/Patchbackup

搜索 目录 ansible 查找

评论


答:

5赞 larsks 8/25/2020 #1

该模块可以说是坏了。该参数仅适用于最终结果集中的项,而不适用于中间目录。findexcludes

也就是说,如果您有这样的目录结构:

toplevel/
  foo/
    testfile1.txt
  bar/
    testfile2.txt

从目录的父级中,运行如下任务:toplevel

- find:
    paths: toplevel
    recurse: true
    excludes: foo
  register: results

结果集将如下所示:

  • toplevel/bar/testfile2.txt
  • toplevel/foo/testfile1.txt

将其与设置进行比较,如下所示:file_type: any

- find:
    paths: toplevel
    file_type: any
    recurse: true
    excludes: foo
  register: results

在本例中,结果集将如下所示:

- `toplevel/bar`
- `toplevel/bar/testfile2.txt`
- `toplevel/foo/testfile1.txt`

请注意,它包含在结果中,但被排除在外。这是因为:toplevel/bartoplevel/foo

  • 我们设置 ,这意味着我们想要查找目录和文件。file_type: any
  • 这将成为结果集的一部分。toplevel/foo
  • 我们从结果中排除了任何带有 basename 的内容foo

如果您仅使用以下命令,您将获得更灵活的行为:find

- name: exclude an intermediate directory with find command
  command: >-
    find toplevel -name foo -prune -o -type f -print
  register: result

这将返回以下项目:

  • toplevel/bar/testfile2.txt

我已经在 github 上放置了上述的可运行版本。

1赞 ilias-sp 8/25/2020 #2

正如你所意识到的,该模块没有为你提供一个选项,让你从根目录开始,但排除其目录之一。您有以下几种选择:find/app

  1. 如果下面的目录不多,您可以使用该子句提供它们的列表(不包括不需要的/apppathsPatchbackup)
  2. 检索 /app 下的所有结果,然后从中筛选出不需要的结果。下面是如何过滤掉它们的示例:/app/Patchbackup

法典:

  - set_fact:
      my_results_final: "{{ my_results_final | default([]) + [item] }}"
    when: item is not regex('^/app/Patchbackup(.+)')
    with_items:
    - "{{ tomjarfound.files }}"


  - debug:
      var: my_results_final

评论

1赞 Ashar 8/25/2020
考虑到我正在处理几种类型的操作系统,我更喜欢使用 ansible 而不是 OS,因为不同操作系统 @ilias-sp @larsks的参数会发生变化findfind
0赞 ilias-sp 8/25/2020
很高兴它有所帮助。因为如果你有很多迭代,循环可能会很耗时,我会说,如果你有数百个结果要输入模块,我会说“操作系统查找”解决方案。如果你不会有很多,那么我认为上述方法也更好。with_itemsset_fact
0赞 Ashar 8/25/2020
是否有规定在操作系统中指定适用于所有风格的 Solaris、Linux 和 Aix 的深度?
0赞 ilias-sp 8/25/2020
我已经很久没有在Solaris和AIX上工作了,现在很难检查。但是你可以运行一个常规的查找,然后将结果提供给一个带有正则表达式过滤器并得到你想要的结果。但同样,如果你不希望有很多结果,我会选择“Ansible”解决方案(我提供的那个)。我看到您正在搜索特定的文件名“test-juli.jar”,所以我想您可能不会有那么多结果!grep
0赞 bmaupin 11/4/2020
虽然这工作正常,但不幸的是,过滤使用将列出输出中每个跳过的项目,这会产生很多噪音。when
2赞 Jaap Joris Vens 8/25/2020 #3

Ansible 的 find 模块的参数对文件的基名进行操作。根据文档:excludes

excludes:一个或多个(shell 或正则表达式)模式,哪种类型由 use_regex 选项控制。基名与排除模式匹配的项目将从模式匹配中剔除。可以使用列表指定多个模式。

在你的例子中,它被正确地忽略了,因为它的基名是 ,但也正确地包括,因为它的基名是 。/app/Patchbackup/Patchbackup/app/Patchbackup/app/apache-test-9.0.10/bin/test-juli.jartest-juli.jar

评论

0赞 bmaupin 11/4/2020
你的解释比其他答案要清楚得多,但我不愿投赞成票,因为它没有为问题提供任何解决方案!(“您能否建议如何从ansible的查找中排除文件夹/app/Patchbackup?
0赞 Jaap Joris Vens 11/4/2020
你是完全正确的。我只是想指出,原始问题中描述的行为是有效的。我应该改用评论。
0赞 bmaupin 11/4/2020
我不知道,这只是一个评论的很多信息。这是描述问题的最佳答案,所以我会投赞成票,以及帮助我解决问题的其他答案之一。我想在这一点上复制其他答案的信息是没有意义的。谢谢!
0赞 Alxsey 4/30/2021 #4

我对这个遗漏的解决方案是使用过滤器:json_query

- find:
    paths: /app
    recurse: true
    patterns: 'test-juli.jar'
  register: results

- set_fact:
    final_result: "{{ results | to_json | from_json | json_query(_query) }}"
  vars:
    _query: "files[?!contains(path, 'Patchbackup')]"

您需要安装 Python 库。(如果我没记错的话,需要该部分来处理另一种类型的问题。jmespath| to_json | from_json |