Как проверить, существует ли файл в Ansible?

131

Мне нужно проверить, существует ли файл в формате /etc/. Если файл существует, мне нужно пропустить задачу. Вот код, который я использую:

- name: checking the file exists
  command: touch file.txt
  when: $(! -s /etc/file.txt)
E Dine Sh
источник

Ответы:

212

Вы можете сначала проверить, существует ли целевой файл или нет, а затем принять решение на основе его результата:

    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 (и тогда будет запущена вторая задача). Вы можете увидеть подробную информацию о модуле статистики здесь: docs.ansible.com/ansible/stat_module.html
Will
1
когда: stat_result.stat.exists определен и stat_result.stat.exists
danday74
2
Спасибо за это. Кроме того, если вы узнали, вы можете написать: when: stat_result.stat.exists == Falseв, when: not stat_result.stat.existsесли хотите, чтобы текст читался более естественно.
racl101
1
Не могли бы вы использовать «not Foo» вместо «Foo == False»?
Матиас
32

Модуль stat сделает это, а также получит много другой информации для файлов. Из примерной документации:

- 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» и т. Д. Вместо «=», «<», «>» и т. Д.
Бузут
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
Rajeshkanna
источник
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
udondan
источник
1
state: fileне создает файлы. См. Docs.ansible.com/ansible/file_module.html
Майкл Крупп,
2
Я бы посчитал первый пример в этом ответе правильным ответом на этот вопрос, основанный на конкретных обстоятельствах вопроса пользователя, использовании пользователем командного модуля и доступных передовых практиках.
apotek
2
vars:
  mypath: "/etc/file.txt"

tasks:
  - name: checking the file exists
    command: touch file.txt
    when: mypath is not exists
DreamUth
источник
2
Вы не поясняете свой ответ, а что when: mypath is not existsв данном случае значит? Разве это не mypathпростая строка?
gcharbon
1
Шаблон Jinja2 помогает здесь проверить путь. Больше примеров в Ansible Docs
DreamUth
10
Обратите внимание, что это проверяет файлы на контроллере, а не на пульте дистанционного управления.
fefe
2

Я считаю, что выполнение большого количества таких .stat.existsпроверок может раздражать и приводить к ошибкам . Например, им требуется дополнительная осторожность, чтобы заставить --checkработать check mode ( ).

Многие ответы здесь предполагают

  • получить и зарегистрироваться
  • применяется, когда выражение регистра истинно

Однако иногда это запах кода, поэтому всегда ищите более эффективные способы использования 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
Опишите в своем ответе, в чем была проблема, и как этот фрагмент поможет ее решить, чтобы помочь другим понять этот ответ
FZs
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

**

Как проверить, существует ли файл в Ansible, используя условие when

**

Ниже приведена игра, которую я использовал для удаления файла, когда файл существует в конце ОС.

 - 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
namasivayam.cse
источник
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, очень полезны для создания абсолютных путей, необходимых для проверки существования.

Federico
источник