Jak sprawdzić, czy plik istnieje w Ansible?


129

Muszę sprawdzić, czy plik istnieje w formacie /etc/. Jeśli plik istnieje, muszę pominąć zadanie. Oto kod, którego używam:

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

Odpowiedzi:


210

Możesz najpierw sprawdzić, czy plik docelowy istnieje, czy nie, a następnie podjąć decyzję na podstawie wyniku:

    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
A jeśli katalog nie istnieje?
ram4nd

2
Jeśli katalog nie istnieje, rejestr stat_resultbędzie miał wartość stat_result.state.existsFalse (i wtedy zostanie uruchomione drugie zadanie). Szczegóły dotyczące modułu statystycznego można znaleźć tutaj: docs.ansible.com/ansible/stat_module.html
Will

1
kiedy: stat_result.stat.exists jest zdefiniowany i stat_result.stat.exists
danday74

2
Dzięki za to. Ponadto, jeśli się dowiesz, możesz napisać: when: stat_result.stat.exists == Falsedo, when: not stat_result.stat.existsjeśli chcesz, aby czytano bardziej naturalnie.
racl101

1
Czy mógłbyś użyć „not Foo” zamiast „Foo == False”?
Matthias Urlichs

32

Stat moduł będzie to zrobić, a także uzyskać wiele innych informacji o plikach. Z przykładowej dokumentacji:

- 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

Wygląda na to, że w najnowszych wersjach pojawia się ostrzeżenie podczas używania „porównań pełnotekstowych”, np. „
Is

24

Można to osiągnąć za pomocą modułu stat, aby pominąć zadanie, gdy plik istnieje.

- 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

Ogólnie rzecz biorąc, można to zrobić za pomocą modułu stat . Ale moduł poleceń ma createsopcję, która czyni to bardzo prostym:

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

Myślę, że twoja komenda dotykowa jest tylko przykładem? Najlepszą praktyką byłoby nie sprawdzanie niczego i pozwolenie ansiblowi wykonać swoją pracę - z odpowiednim modułem. Więc jeśli chcesz mieć pewność, że plik istnieje, użyj modułu pliku:

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

1
state: filenie tworzy plików. Zobacz docs.ansible.com/ansible/file_module.html
Michael Krupp

2
Pierwszy przykład w tej odpowiedzi uznałbym za właściwą odpowiedź na to pytanie, w oparciu o specyficzne okoliczności pytania użytkownika, użycie przez użytkownika modułu poleceń i najlepsze praktyki ansibli.
apotek

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

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

2
Nie wyjaśniasz swojej odpowiedzi, a co when: mypath is not existsw tym przypadku oznacza? Czy nie jest mypathto zwykły ciąg?
gcharbon

1
Szablon Jinja2 pomaga tutaj sprawdzić poprawność ścieżki. Więcej przykładów w Ansible Docs
DreamUth

10
Zauważ, że sprawdza to pliki na kontrolerze, a nie na pilocie.
fefe

2

Uważam, że wykonywanie wielu tego .stat.existstypu kontroli może być denerwujące i podatne na błędy . Na przykład wymagają dodatkowej uwagi, aby uzyskać działanie trybu sprawdzania ( --check).

Wiele odpowiedzi sugeruje tutaj

  • pobierz i zarejestruj się
  • stosuje się, gdy wyrażenie rejestru jest prawdziwe

Jednak czasami jest to zapach kodu, więc zawsze szukaj lepszych sposobów korzystania z Ansible, w szczególności korzystanie z odpowiedniego modułu ma wiele zalet. na przykład

- name: install ntpdate
  package:
    name: ntpdate

lub

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

Ale jeśli nie jest to możliwe, użyj jednego modułu, sprawdź również, czy możesz się zarejestrować i sprawdzić wynik poprzedniego zadania. na przykład

# 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'

Zanotuj when:ale również creates:tak --checknie z błędów

Wspominam o tym, ponieważ często te mniej niż idealne praktyki występują w parach, tj. Nie ma pakietu apt / yum, więc musimy 1) pobrać i 2) rozpakować

Mam nadzieję że to pomoże


2

Odkryto, że wywołanie statjest powolne i zbiera wiele informacji, które nie są wymagane do sprawdzenia istnienia pliku.
Po spędzeniu czasu na poszukiwaniu rozwiązania odkryłem następujące rozwiązanie, które działa znacznie szybciej:

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

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

1
Opisz w swojej odpowiedzi, na czym polegał problem i jak ten fragment go rozwiąże, aby pomóc innym zrozumieć tę odpowiedź
FZ,

1

Możesz użyć modułu Ansible stat , aby zarejestrować plik i kiedy moduł zastosować warunek.

- 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

**

Jak sprawdzić, czy plik istnieje w Ansible przy użyciu warunku When

**

Poniżej znajduje się gra ansible, której użyłem do usunięcia pliku, gdy istnieje on na końcu systemu operacyjnego.

 - 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

Użyłem warunku gry jak poniżej

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

możesz podać prawda / fałsz na podstawie swoich wymagań

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

0

Jeśli chcesz się tylko upewnić, że pewien plik istnieje (np. Ponieważ powinien być utworzony w inny sposób niż przez ansibla) i zawieść, jeśli tak się nie stanie, możesz to zrobić:

- 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

Uwaga na temat ścieżek względnych w celu uzupełnienia innych odpowiedzi.

Robiąc infrastrukturę jako kod, zwykle używam ról i zadań, które akceptują ścieżki względne, szczególnie dla plików zdefiniowanych w tych rolach.

Specjalne zmienne, takie jak playbook_dir i role_path, są bardzo przydatne do tworzenia bezwzględnych ścieżek potrzebnych do sprawdzenia istnienia.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.