如何使用 Ansible 创建空文件?

问题描述 投票:0回答:10

使用 Ansible 创建空文件的最简单方法是什么?我知道我可以将一个空文件保存到

files
目录中,然后将其复制到远程主机,但我发现这有点不令人满意。

另一种方法是触摸远程主机上的文件:

- name: create fake 'nologin' shell
  file: path=/etc/nologin state=touch owner=root group=sys mode=0555

但是文件每次都会被触及,在日志中显示为一条黄线,这也令人不满意......

这个简单的问题有更好的解决办法吗?

file ansible
10个回答
262
投票

文件模块的文档说:

如果

state=file
,如果文件不存在,则不会创建该文件,如果您想要该行为,请参阅复制或模板模块。

因此我们使用 copy 模块,仅当文件尚不存在时使用

force: false
创建一个新的空文件(如果文件存在,则保留其内容)。

- name: ensure file exists
  copy:
    content: ""
    dest: /etc/nologin
    force: false
    group: sys
    owner: root
    mode: 0555

这是一个声明式且优雅的解决方案。


42
投票

类似这样的东西(首先使用

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
功能。


36
投票

仅限 ansible 2.7+

Ansible

file
模块提供了一种在不修改文件时间的情况下触摸文件的方法。

- name: touch a file, but do not change access time, making this 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


31
投票

另一个选项,使用命令模块:

- name: Touch file only when it does not exists
  command: touch /path/to/file
  args:
    creates: /path/to/file

creates
参数确保如果文件存在则不执行此操作(因此是幂等的)。


16
投票

基于已接受的答案,如果您希望在每次运行时检查文件的权限,并且如果文件存在,则这些权限会相应更改,或者如果文件不存在,则仅创建文件,您可以使用以下命令:

- 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"}}

11
投票

file: path=/etc/nologin state=touch

完全相当于 touch(1.4+ 中的新增功能) - 如果您不想更改文件时间戳,请使用 stat。


3
投票

事实证明,我没有足够的声誉来将此作为评论,这将是更合适的地方:

回复。 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" }}'

1
投票

如果文件不存在则更改。创建空文件。

- name: create fake 'nologin' shell
  file:
    path: /etc/nologin
    state: touch
  register: p
  changed_when: p.diff.before.state == "absent"

1
投票

两个答案的组合,有一点不同。 当创建文件或更新权限时,代码将被检测为更改。

- 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

0
投票

为了使用临时命令在远程计算机中创建文件

ansible client -m file -a"dest=/tmp/file state=touch"

如有错误请指正

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.