问题
I need to create an Ansible playbook to delete the *.web
files in a specific directory only if the files exists.
OS : cent OS, Redhat 5x, 6x.
I have tried the following with no success:
- stat: path=/opt/app/jboss/configuration/*.web
register: web
- shell: rm -rf /opt/app/jboss/configuration/*.web
when: web.stat.exists
回答1:
@bruce-p's answer gives a deprecation warning with Ansible 2.0+, but the new with_fileglob gives another option:
- file: path={{ item }} state=absent
with_fileglob: /opt/app/jboss/configuration/*.web
(Similar question remove all files containing a certain name within a directory has a similar answer.)
EDIT: As noted below, that won't work; here's an example of "the fancy way":
- find:
paths: /opt/app/jboss/configuration
patterns: "*.web"
register: find_results
- file:
path: "{{ item['path'] }}"
state: absent
with_items: "{{ find_results['files'] }}"
回答2:
The stat module does not work with wildcards, so the first task will not do what you expect. Most Ansible modules do not support *
, ?
, etc. wildcards in their parameters unless explicitly documented that they do. The reason for this is that wildcard expansion is typically handled by your login shell (bash, zsh, etc), so unless the application explicitly supports it then it won't recognize them.
Here's an easy way to verify this:
tasks:
- stat: path=/etc/*.conf
register: foo
- debug: var=foo
- stat: path=/etc/resolv.conf
register: bar
- debug: var=bar
The output of this is:
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
}
}
}
}
Note that when you specify a single file it returns the results for that file, but when you specify a wildcard it basically returns nothing.
As @udondan implied in his answer, you can just do something like this:
- shell: rm -rf /opt/app/jboss/configuration/*.web
Since rm
will silently complete without error if there are 0 matches.
If you really want to get fancy you could use the find module to locate all the files that match your pattern and then invoke the rm
command (or better yet use the file module and set state=absent
) using a with_items loop to loop over what find
returns.
回答3:
rm -rf
does not care if the files exist or not. It will not complain. If the files exist they will be removed. If not, well, then not. But the outcome is the same: same status code, no output. No need to deal with that on Ansible level then.
来源:https://stackoverflow.com/questions/34949595/how-to-delete-web-files-only-if-they-exist