2016-01-22 52 views
-1

我需要创建一个Ansible剧本删除仅如果文件存在特定的目录中*.web文件。如何删除*名.web文件,只有当他们存在

OS:百分之操作系统,红帽的5倍,6倍。

我曾尝试没有成功如下:

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

你得到什么错误?为什么在删除之前测试存在? – helloV

+0

对不起,这是我的错误。我有一个像'mv','cp'和''rm'多重要求* .web'只有当文件存在。我已经验证了'mv和cp * web',它失败了,并且没有这样的文件或目录中止......只是注意到'rm'正在悄悄地完成而没有错误。 – miki

回答

0

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

+0

只有Ansible会抱怨:'[警告]:考虑使用状态=缺席而不是运行rm的文件模块' – dokaspar

1

的统计模块不使用通配符工作,所以第一个任务不会做你期望的。大多数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 

由于rm将没有错误默默地完整,如果有0匹配。

如果你真的想获得看上你可以使用find模块找到所有匹配您的模式,该文件,然后调用rm命令(或更好,但使用file模块,并设置state=absent)使用with_items循环来在find返回。

+0

感谢您的解释,刚才注意到'rm'正在默默地完成没有错误...我有相同的情况' mv或​​cp * .web'只有文件存在。请让我知道这个建议,我试过'find',但它没有抛出这样的文件或目录错误。 – miki

+0

我试过' - shell:find/opt/app/jboss/configuration/-name“* .web”-print0 | xargs -0 -I {} mv {}/backup',它的工作方式如同例外。谢谢! – miki

4

@布鲁斯-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'] }}" 
+2

这是行不通的,因为'with_fileglob'只匹配运行正常的系统上的文件,而不是目标主机上的文件。 –

+0

嗯,你是对的! @ bruce-p的评论“如果你真的想变得很花哨,你可以使用find模块找到所有符合你的模式的文件,然后调用rm命令(或者更好地使用文件模块并设置state = absent) with_items循环以查找返回结果。“是干净的方式来做到这一点,我想 - 编辑包括一个例子。 –

相关问题