Як перевірити, чи існує файл у Ansible?


128

Я повинен перевірити, чи існує файл у /etc/ . Якщо файл існує, я повинен пропустити завдання. Ось код, який я використовую:

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

Відповіді:


208

Спочатку ви можете перевірити, чи існує цільовий файл чи ні, а потім прийняти рішення, виходячи з результату його результату:

    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.existsвказано значення False (і тоді виконується друге завдання). Детальну інформацію про модуль stat можна переглянути тут: docs.ansible.com/ansible/stat_module.html
Чи буде

1
коли: stat_result.stat.exists визначено, а stat_result.stat.exists
danday74

2
Дякую за це Крім того, якщо ви знайдете, ви можете написати: when: stat_result.stat.exists == Falseto, when: not stat_result.stat.existsякщо ви хочете, щоб він читав більш природне.
racl101

1
Будь ласка, використовуйте "не 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

Схоже, що в останніх версіях є попередження, коли використовується "повні текстові порівняння" типу "є" тощо замість "=", "<", ">" тощо.
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

Я думаю, ваша команда touch - лише приклад? Найкращою практикою було б взагалі нічого не перевіряти і дозволити відповідальним робити свою роботу - за допомогою правильного модуля. Отже, якщо ви хочете переконатися, що файл існує, ви використовуєте модуль файлів:

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

1
state: fileне створює файли. Дивіться docs.ansible.com/ansible/file_module.html
Майкл Крупп

2
Я б вважав першим прикладом у цій відповіді правильну відповідь на це запитання, виходячи з конкретних обставин запитання користувача, використання користувачем командного модуля та найкращих практичних принципів Ansible.
апотек

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

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
Опишіть, будь ласка, у своїй відповіді, у чому проблема, і як цей фрагмент вирішить її, щоб допомогти іншим зрозуміти цю відповідь
FZs

1

Ви можете використовувати модуль Ansible stat для реєстрації файлу, а коли модуль застосувати умову.

- 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, використовуючи при умові

**

Нижче представлена ​​анкета, яка використовується для видалення файлу, коли файл існує в кінці ОС.

 - 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

Якщо ви просто хочете переконатися, що певний файл існує (f.ex. тому, що він повинен бути створений інакше, ніж через 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, дуже корисні для створення абсолютних шляхів, необхідних для перевірки на існування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.