如何使用 Ansible 创建一个空文件?
How to create an empty file with Ansible?
使用 Ansible 创建空文件的最简单方法是什么?我知道我可以将一个空文件保存到 files
目录中,然后将其复制到远程主机,但我发现这有点不尽如人意。
另一种方法是触摸远程主机上的文件:
- name: create fake 'nologin' shell
file: path=/etc/nologin state=touch owner=root group=sys mode=0555
但是后来每次都摸到文件,在日志中显示为黄线,同样不尽如人意...
这个简单的问题有更好的解决方案吗?
这样的事情(首先使用 stat
模块收集有关它的数据,然后使用条件过滤)应该有效:
- stat: path=/etc/nologin
register: p
- name: create fake 'nologin' shell
file: path=/etc/nologin state=touch owner=root group=sys mode=0555
when: p.stat.exists is defined and not p.stat.exists
您也可以利用 changed_when
功能。
另一种选择,使用命令模块:
- name: Create file
command: touch /path/to/file
args:
creates: /path/to/file
'creates' 参数确保如果文件存在则不执行此操作。
基于已接受的答案,如果您希望在每个 运行 上检查文件的权限,并且如果文件存在则相应更改,或者如果文件不存在则创建文件,您可以使用以下内容:
- stat: path=/etc/nologin
register: p
- name: create fake 'nologin' shell
file: path=/etc/nologin
owner=root
group=sys
mode=0555
state={{ "file" if p.stat.exists else "touch"}}
文件模块的文档说
If state=file
, the file will NOT be created if it does not exist, see the copy or template module if you want that behavior.
所以我们使用copy module,使用force=no
只在文件不存在时创建一个新的空文件(如果文件存在,其内容被保留)。
- name: ensure file exists
copy:
content: ""
dest: /etc/nologin
force: no
group: sys
owner: root
mode: 0555
这是一个声明式的优雅解决方案。
file: path=/etc/nologin state=touch
完全等同于 touch(1.4+ 中的新功能)- 如果您不想更改文件时间戳,请使用 stat。
原来我没有足够的声誉把它作为评论,这将是一个更合适的地方:
回复。 AllBlackt 的回答,如果你更喜欢 Ansible 的多行格式,你需要调整 state
的引号(我花了几分钟解决这个问题,所以希望这能加快别人的速度),
- stat:
path: "/etc/nologin"
register: p
- name: create fake 'nologin' shell
file:
path: "/etc/nologin"
owner: root
group: sys
mode: 0555
state: '{{ "file" if p.stat.exists else "touch" }}'
为了使用临时命令在远程机器上创建文件
ansible client -m file -a"dest=/tmp/file state=touch"
如有错误请指正
如果文件不存在则更改。创建空文件。
- name: create fake 'nologin' shell
file:
path: /etc/nologin
state: touch
register: p
changed_when: p.diff.before.state == "absent"
仅支持 ansible 2.7+
Ansible file
模块提供了一种在不修改文件时间的情况下访问文件的方法。
- name: Touch again the same file, but dont change times this makes the task idempotent
file:
path: /etc/foo.conf
state: touch
mode: u+rw,g-wx,o-rwx
modification_time: preserve
access_time: preserve
参考:
https://docs.ansible.com/ansible/latest/modules/file_module.html
两个答案的组合,有一个转折。当创建文件或更新权限时,代码将被检测为已更改。
- name: Touch again the same file, but dont change times this makes the task idempotent
file:
path: /etc/foo.conf
state: touch
mode: 0644
modification_time: preserve
access_time: preserve
changed_when: >
p.diff.before.state == "absent" or
p.diff.before.mode|default("0644") != "0644"
还有一个版本也可以更正所有者和组,并在更正这些时检测到它已更改:
- name: Touch again the same file, but dont change times this makes the task idempotent
file:
path: /etc/foo.conf
state: touch
state: touch
mode: 0644
owner: root
group: root
modification_time: preserve
access_time: preserve
register: p
changed_when: >
p.diff.before.state == "absent" or
p.diff.before.mode|default("0644") != "0644" or
p.diff.before.owner|default(0) != 0 or
p.diff.before.group|default(0) != 0
使用 Ansible 创建空文件的最简单方法是什么?我知道我可以将一个空文件保存到 files
目录中,然后将其复制到远程主机,但我发现这有点不尽如人意。
另一种方法是触摸远程主机上的文件:
- name: create fake 'nologin' shell
file: path=/etc/nologin state=touch owner=root group=sys mode=0555
但是后来每次都摸到文件,在日志中显示为黄线,同样不尽如人意...
这个简单的问题有更好的解决方案吗?
这样的事情(首先使用 stat
模块收集有关它的数据,然后使用条件过滤)应该有效:
- stat: path=/etc/nologin
register: p
- name: create fake 'nologin' shell
file: path=/etc/nologin state=touch owner=root group=sys mode=0555
when: p.stat.exists is defined and not p.stat.exists
您也可以利用 changed_when
功能。
另一种选择,使用命令模块:
- name: Create file
command: touch /path/to/file
args:
creates: /path/to/file
'creates' 参数确保如果文件存在则不执行此操作。
基于已接受的答案,如果您希望在每个 运行 上检查文件的权限,并且如果文件存在则相应更改,或者如果文件不存在则创建文件,您可以使用以下内容:
- stat: path=/etc/nologin
register: p
- name: create fake 'nologin' shell
file: path=/etc/nologin
owner=root
group=sys
mode=0555
state={{ "file" if p.stat.exists else "touch"}}
文件模块的文档说
If
state=file
, the file will NOT be created if it does not exist, see the copy or template module if you want that behavior.
所以我们使用copy module,使用force=no
只在文件不存在时创建一个新的空文件(如果文件存在,其内容被保留)。
- name: ensure file exists
copy:
content: ""
dest: /etc/nologin
force: no
group: sys
owner: root
mode: 0555
这是一个声明式的优雅解决方案。
file: path=/etc/nologin state=touch
完全等同于 touch(1.4+ 中的新功能)- 如果您不想更改文件时间戳,请使用 stat。
原来我没有足够的声誉把它作为评论,这将是一个更合适的地方:
回复。 AllBlackt 的回答,如果你更喜欢 Ansible 的多行格式,你需要调整 state
的引号(我花了几分钟解决这个问题,所以希望这能加快别人的速度),
- stat:
path: "/etc/nologin"
register: p
- name: create fake 'nologin' shell
file:
path: "/etc/nologin"
owner: root
group: sys
mode: 0555
state: '{{ "file" if p.stat.exists else "touch" }}'
为了使用临时命令在远程机器上创建文件
ansible client -m file -a"dest=/tmp/file state=touch"
如有错误请指正
如果文件不存在则更改。创建空文件。
- name: create fake 'nologin' shell
file:
path: /etc/nologin
state: touch
register: p
changed_when: p.diff.before.state == "absent"
仅支持 ansible 2.7+
Ansible file
模块提供了一种在不修改文件时间的情况下访问文件的方法。
- name: Touch again the same file, but dont change times this makes the task idempotent
file:
path: /etc/foo.conf
state: touch
mode: u+rw,g-wx,o-rwx
modification_time: preserve
access_time: preserve
参考: https://docs.ansible.com/ansible/latest/modules/file_module.html
两个答案的组合,有一个转折。当创建文件或更新权限时,代码将被检测为已更改。
- name: Touch again the same file, but dont change times this makes the task idempotent
file:
path: /etc/foo.conf
state: touch
mode: 0644
modification_time: preserve
access_time: preserve
changed_when: >
p.diff.before.state == "absent" or
p.diff.before.mode|default("0644") != "0644"
还有一个版本也可以更正所有者和组,并在更正这些时检测到它已更改:
- name: Touch again the same file, but dont change times this makes the task idempotent
file:
path: /etc/foo.conf
state: touch
state: touch
mode: 0644
owner: root
group: root
modification_time: preserve
access_time: preserve
register: p
changed_when: >
p.diff.before.state == "absent" or
p.diff.before.mode|default("0644") != "0644" or
p.diff.before.owner|default(0) != 0 or
p.diff.before.group|default(0) != 0