Ansible 如何仅删除存在的*.web文件

Ansible 如何仅删除存在的*.web文件,ansible,ansible-playbook,Ansible,Ansible Playbook,我需要创建一个Ansible playbook来删除特定目录中的*.web文件,前提是这些文件存在 操作系统:分操作系统,红帽5x,6x 我尝试了以下方法,但没有成功: - stat: path=/opt/app/jboss/configuration/*.web register: web - shell: rm -rf /opt/app/jboss/configuration/*.web when: web.stat.exists rm-rf不关心文件是否存在。它不会抱怨。

我需要创建一个Ansible playbook来删除特定目录中的
*.web
文件,前提是这些文件存在

操作系统:分操作系统,红帽5x,6x

我尝试了以下方法,但没有成功:

 - stat: path=/opt/app/jboss/configuration/*.web
   register: web
 - shell: rm -rf /opt/app/jboss/configuration/*.web
   when: web.stat.exists

rm-rf
不关心文件是否存在。它不会抱怨。如果文件存在,它们将被删除。如果不是,那么就不是。但结果是一样的:相同的状态代码,没有输出。无需在Ansible级别处理该问题。

stat模块不使用通配符,因此第一个任务不会完成您期望的任务。大多数Ansible模块在其参数中不支持
*
等通配符,除非明确说明它们支持通配符。原因是通配符扩展通常由您的登录shell(bash、zsh等)处理,因此除非应用程序明确支持它,否则它将无法识别它们

这里有一个简单的方法来验证这一点:

tasks:
  - stat: path=/etc/*.conf
    register: foo

  - debug: var=foo

  - stat: path=/etc/resolv.conf
    register: bar

  - debug: var=bar
其输出为:

ok: [localhost] => {
    "var": {
        "foo": {
            "changed": false,
            "invocation": {
                "module_args": "path=/etc/*.conf",
                "module_complex_args": {},
                "module_name": "stat"
            },
            "stat": {
                "exists": false
            }
        }
    }
}

TASK: [stat path=/etc/resolv.conf] ********************************************
ok: [localhost]

TASK: [debug var=bar] *********************************************************
ok: [localhost] => {
    "var": {
        "bar": {
            "changed": false,
            "invocation": {
                "module_args": "path=/etc/resolv.conf",
                "module_complex_args": {},
                "module_name": "stat"
            },
            "stat": {
                "atime": 1446665095.0724516,
                "checksum": "fd75f8cc67e4879fa546cbbd901b211bcb7e1b5e",
                "ctime": 1446840004.4182615,
                "dev": 51713,
                "exists": true,
                "gid": 0,
                "gr_name": "root",
                "inode": 146096,
                "isblk": false,
                "ischr": false,
                "isdir": false,
                "isfifo": false,
                "isgid": false,
                "islnk": false,
                "isreg": true,
                "issock": false,
                "isuid": false,
                "md5": "a56ca5f7379429d3b358ce922b28039b",
                "mode": "0644",
                "mtime": 1446840004.4182615,
                "nlink": 1,
                "path": "/etc/resolv.conf",
                "pw_name": "root",
                "rgrp": true,
                "roth": true,
                "rusr": true,
                "size": 94,
                "uid": 0,
                "wgrp": false,
                "woth": false,
                "wusr": true,
                "xgrp": false,
                "xoth": false,
                "xusr": false
            }
        }
    }
}
请注意,当您指定单个文件时,它将返回该文件的结果,但当您指定通配符时,它基本上不会返回任何结果

正如@udondan在他的回答中暗示的那样,你可以这样做:

- shell: rm -rf /opt/app/jboss/configuration/*.web
因为如果有0个匹配项,
rm
将自动完成,不会出错


如果您真的想变得有趣,您可以使用该模块找到与您的模式匹配的所有文件,然后调用
rm
命令(或者更好地使用该模块并设置
state=缺席
)使用with_items循环来循环查找返回的内容。

@bruce-p的回答给出了Ansible 2.0+的弃用警告,但新的with_fileglob提供了另一个选项:

- file: path={{ item }} state=absent
  with_fileglob: /opt/app/jboss/configuration/*.web
(类似的问题也有类似的答案。)

编辑:如下所述,这不起作用;下面是一个“奇特方式”的例子:


你犯了什么错误?为什么要在删除之前测试存在性?对不起,这是我的错误。我有多种要求,如
mv
cp
rm
*。只有在文件存在时,我才有web
。我已经验证了
mv和cp*web
,但失败并中止,没有这样的文件或目录…刚刚注意到
rm
正在以无误的方式完成。感谢您的解释,刚刚注意到
rm
正在以无误的方式完成。。。仅当文件存在时,我对
mv或cp*.web
有相同的场景。请让我知道这个建议,我尝试了
find
,但它没有抛出这样的文件或目录错误。我尝试了
-shell:find/opt/app/jboss/configuration/-name“*.web”-print0 | xargs-0-I{}mv/backup
并且它作为例外工作。谢谢这不起作用,因为
with_fileglob
只匹配运行ansible的系统上的文件,而不是目标主机上的文件。嗯,你说得对@bruce-p的评论“如果你真的想变得更有趣,你可以使用find模块找到所有与你的模式匹配的文件,然后调用rm命令(或者更好地使用file模块并设置state=缺席),使用with_items循环查找返回的内容。”这是一种干净的方法,我想编辑一个例子,只有ANNESS会抱怨:<代码> [警告]:考虑使用状态为缺省的文件模块,而不是运行RM
- find:
    paths: /opt/app/jboss/configuration
    patterns: "*.web"
  register: find_results

- file:
    path: "{{ item['path'] }}"
    state: absent
  with_items: "{{ find_results['files'] }}"