如何删除* .web文件只有它们存在

时间:2016-01-22 14:57:12

标签: ansible ansible-playbook

我需要创建一个Ansible playbook,只有在文件存在时才删除特定目录中的*.web文件。

OS:分OS,Redhat 5x,6x。

我尝试过以下操作但没有成功:

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

3 个答案:

答案 0 :(得分:14)

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

- file: path={{ item }} state=absent
  with_fileglob: /opt/app/jboss/configuration/*.web

(类似问题remove all files containing a certain name within a directory也有类似的答案。)

编辑:如下所述,这不会奏效;这是"花哨方式的一个例子":

- find:
    paths: /opt/app/jboss/configuration
    patterns: "*.web"
  register: find_results

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

答案 1 :(得分:2)

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将无声地完成而不会出错。

如果你真的想要开心,可以使用find模块找到与你的模式匹配的所有文件,然后调用rm命令(或者更好地使用file模块并设置state=absent)使用with_items循环来循环find返回的内容。

答案 2 :(得分:0)

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