如何解决Ansible查找模块不排除搜索中的文件夹
这是我的剧本,我尝试在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
吗?
解决方法
find
模块可能已损坏。 excludes
参数仅适用于最终结果集中的项目,不适用于中间目录。
也就是说,如果您具有这样的目录结构:
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/bar
,但排除了toplevel/foo
。那是因为:
- 我们设置了
file_type: any
,这意味着我们要查找目录和文件。 - 这使
toplevel/foo
成为结果集的一部分。 - 我们从结果中排除任何具有基名
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
我已经放置了上述on github的可运行版本。
, Ansible的find模块的excludes
参数在文件的基名上运行。根据文档:
排除:一种或多种(shell或正则表达式)模式,其类型由use_regex选项控制。基本名称与排除模式匹配的项目将从模式匹配中剔除。可以使用列表指定多个模式。
对于您而言,它正确地忽略了/app/Patchbackup/
,因为它的基本名称是Patchbackup
,但是也正确地包含了/app/Patchbackup/app/apache-test-9.0.10/bin/test-juli.jar
,因为它的基本名称是test-juli.jar
。
您意识到,find
模块没有为您提供以/app
的根目录开头但可以排除其目录之一的选项。您有几种选择:
- 如果
/app
下的目录不多,则可以使用子句paths
提供它们的列表(不希望的Patchbackup
除外) - 检索/ 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
,
我对这个遗漏的解决方案是使用 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')]"
您需要安装 jmespath
python 库。 (如果我没记错的话,需要 | to_json | from_json |
部分来处理其他类型的问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。