如何检查Ansible中是否存在文件?


128

我必须检查中是否存在文件/etc/。如果文件存在,那么我必须跳过任务。这是我正在使用的代码:

- name: checking the file exists
  command: touch file.txt
  when: $(! -s /etc/file.txt)

Answers:


206

您可以首先检查目标文件是否存在,然后根据其结果输出做出决定:

    tasks:
      - name: Check that the somefile.conf exists
        stat:
          path: /etc/file.txt
        register: stat_result

      - name: Create the file, if it doesnt exist already
        file:
          path: /etc/file.txt
          state: touch
        when: not stat_result.stat.exists

1
如果目录不存在怎么办?
ram4nd

2
如果该目录不存在,则寄存器stat_result将具有stat_result.state.existsFalse(即第二个任务运行时)。您可以在此处查看stat模块的详细信息:docs.ansible.com/ansible/stat_module.html
将于

1
时间:stat_result.stat.exists已定义且
stat_result.stat.exists

2
谢谢你 同样,如果发现,您可以编写:when: stat_result.stat.exists == False至,when: not stat_result.stat.exists如果您希望它阅读得更自然。
racl101

1
您是否可以使用“ not Foo”代替“ Foo == False”?
Matthias Urlichs

32

统计模块将做到这一点,以及获得许多其他信息的文件。从示例文档中:

- stat: path=/path/to/something
  register: p

- debug: msg="Path exists and is a directory"
  when: p.stat.isdir is defined and p.stat.isdir

在最新版本中,使用“全文比较”(例如“ is”等)代替“ =“,” <“,”>“>等时
会有警告。– Buzut

24

这可以通过stat模块在文件存在时跳过任务来实现。

- hosts: servers
  tasks:
  - name: Ansible check file exists.
    stat:
      path: /etc/issue
    register: p
  - debug:
      msg: "File exists..."
    when: p.stat.exists
  - debug:
      msg: "File not found"
    when: p.stat.exists == False

16

通常,您可以使用stat模块执行此操作。但是命令模块具有creates使此操作非常简单的选项:

- name: touch file
  command: touch /etc/file.txt
  args:
    creates: /etc/file.txt

我想您的触摸命令只是一个例子?最佳实践是根本不检查任何东西,而让ansible进行工作-使用正确的模块。因此,如果要确保文件存在,可以使用文件模块:

- name: make sure file exists
  file:
    path: /etc/file.txt
    state: touch

1
state: file不创建文件。参见docs.ansible.com/ansible/file_module.html
Michael

2
我将根据用户问题的具体情况,用户对命令模块的使用以及可行的最佳实践,将此答案中的第一个示例视为该问题的正确答案。
apotek '19

2
vars:
  mypath: "/etc/file.txt"

tasks:
  - name: checking the file exists
    command: touch file.txt
    when: mypath is not exists

2
您不解释您的答案,when: mypath is not exists在这种情况下是什么意思?这不是mypath一个简单的字符串吗?
gcharbon

1
Jinja2模板在这里有助于验证路径。Ansible Docs中的
DreamUth 18'Aug

10
请注意,这会检查控制器上而不是遥控器上的文件。
fefe

2

我发现这样做很多.stat.exists类型检查可能很烦人并且容易出错。例如,他们需要格外小心才能使检查模式(--check)工作。

这里有很多答案建议

  • 获取并注册
  • 当寄存器表达式为真时适用

但是,有时这是一种代码味道,因此始终寻找使用Ansible的更好方法,特别是使用正确的模块有很多优点。例如

- name: install ntpdate
  package:
    name: ntpdate

要么

- file:
    path: /etc/file.txt
    owner: root
    group: root
    mode: 0644

但是,当不可能使用一个模块时,还要调查是否可以注册并检查上一个任务的结果。例如

# jmeter_version: 4.0 
- name: Download Jmeter archive
  get_url:
    url: "http://archive.apache.org/dist/jmeter/binaries/apache-jmeter-{{ jmeter_version }}.tgz"
    dest: "/opt/jmeter/apache-jmeter-{{ jmeter_version }}.tgz"
    checksum: sha512:eee7d68bd1f7e7b269fabaf8f09821697165518b112a979a25c5f128c4de8ca6ad12d3b20cd9380a2b53ca52762b4c4979e564a8c2ff37196692fbd217f1e343
  register: download_result

- name: Extract apache-jmeter
  unarchive:
    src: "/opt/jmeter/apache-jmeter-{{ jmeter_version }}.tgz"
    dest: "/opt/jmeter/"
    remote_src: yes
    creates: "/opt/jmeter/apache-jmeter-{{ jmeter_version }}"
  when: download_result.state == 'file'

请注意when:,但也creates:因此--check不会报错了

我之所以这样说是因为这些不理想的做法通常成对出现,即没有apt / yum包,因此我们必须1)下载和2)解压缩

希望这可以帮助


2

发现调用stat速度很慢,并且会收集很多文件存在检查不需要的信息。
花了一些时间寻找解决方案之后,我发现了以下解决方案,它的运行速度更快:

- raw: test -e /path/to/something && echo true || echo false
  register: file_exists

- debug: msg="Path exists"
  when: file_exists == true

1
请在您的答案中说明问题所在,以及如何解决此
摘要

1

您可以使用Ansible stat模块注册文件,以及使用when模块应用条件。

- name: Register file
      stat:
        path: "/tmp/test_file"
      register: file_path

- name: Create file if it doesn't exists
      file: 
        path: "/tmp/test_file"
        state: touch
      when: file_path.stat.exists == False

0

**

如何使用when条件检查Ansible中是否存在文件

**

以下是当文件存在于操作系统端时用于删除文件的ansible播放。

 - name: find out /etc/init.d/splunk file exists or not'
      stat:
        path: /etc/init.d/splunk
      register: splunkresult
      tags:
        - always

    - name: 'Remove splunk from init.d file if splunk already running'
      file:
        path: /etc/init.d/splunk
        state: absent
      when: splunkresult.stat.exists == true
      ignore_errors: yes
      tags:
        - always

我已经使用了如下的播放条件

when: splunkresult.stat.exists == true --> Remove the file

您可以根据需要提供对/错

when: splunkresult.stat.exists == false
when: splunkresult.stat.exists == true

0

如果您只是想确保某个文件存在(例如,因为应该以不同于通过ansible的方式创建文件)并且如果没有则失败,则可以执行以下操作:

- name: sanity check that /some/path/file exists
  command: stat /some/path/file
  check_mode: no # always run
  changed_when: false # doesn't change anything

0

有关相对路径的注释,以补充其他答案。

在将基础结构用作代码时,我通常使用角色和任务来接受相对路径,特别是针对那些角色中定义的文件。

诸如playbook_dir和role_path之类的特殊变量对于创建测试存在性所需的绝对路径非常有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.