Wie überprüfe ich, ob eine Datei in Ansible vorhanden ist?

128

Ich muss überprüfen, ob eine Datei in existiert /etc/. Wenn die Datei existiert, muss ich die Aufgabe überspringen. Hier ist der Code, den ich verwende:

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

Antworten:

206

Sie können zuerst überprüfen, ob die Zieldatei vorhanden ist oder nicht, und dann basierend auf der Ausgabe des Ergebnisses eine Entscheidung treffen:

    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
Arbab Nazar
quelle
1
Was ist, wenn das Verzeichnis nicht existiert?
Ram4nd
2
Wenn das Verzeichnis nicht vorhanden ist, hat das Register den stat_resultWert stat_result.state.existsFalse (und dann wird die zweite Task ausgeführt). Sie können Details des stat-Moduls hier sehen: docs.ansible.com/ansible/stat_module.html
Will
1
wenn: stat_result.stat.exists definiert ist und stat_result.stat.exists
danday74
2
Danke dafür. Wenn Sie es herausgefunden haben, können Sie auch schreiben: when: stat_result.stat.exists == Falsean, when: not stat_result.stat.existswenn Sie möchten, dass es natürlicher liest.
racl101
1
Würden Sie bitte "nicht Foo" anstelle von "Foo == False" verwenden?
Matthias Urlichs
32

Das stat- Modul erledigt dies und erhält viele andere Informationen für Dateien. Aus der Beispieldokumentation:

- 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
Bruce P.
quelle
Sieht aus wie in den neuesten Versionen, es gibt eine Warnung, wenn "Volltextvergleiche" wie "ist" usw. anstelle von "=", "<", ">" usw. verwendet werden
Buzut
24

Dies kann mit dem stat-Modul erreicht werden, um die Aufgabe zu überspringen, wenn eine Datei vorhanden ist.

- 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
quelle
16

Im Allgemeinen würden Sie dies mit dem stat-Modul tun . Das Befehlsmodul hat jedoch die createsOption, die dies sehr einfach macht:

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

Ich denke, Ihr Touch-Befehl ist nur ein Beispiel? Die beste Vorgehensweise wäre, überhaupt nichts zu überprüfen und ansible seine Arbeit machen zu lassen - mit dem richtigen Modul. Wenn Sie also sicherstellen möchten, dass die Datei vorhanden ist, verwenden Sie das Dateimodul:

- name: make sure file exists
  file:
    path: /etc/file.txt
    state: touch
Udondan
quelle
1
state: fileerstellt keine Dateien. Siehe docs.ansible.com/ansible/file_module.html
Michael Krupp
2
Ich würde das erste Beispiel in dieser Antwort als die richtige Antwort auf diese Frage betrachten, basierend auf den spezifischen Umständen der Frage des Benutzers, der Verwendung des Befehlsmoduls durch den Benutzer und ansiblen Best Practices.
Apotek
2
vars:
  mypath: "/etc/file.txt"

tasks:
  - name: checking the file exists
    command: touch file.txt
    when: mypath is not exists
DreamUth
quelle
2
Sie erklären Ihre Antwort nicht und was bedeutet when: mypath is not existsdas in diesem Fall? Ist das nicht mypatheine einfache Zeichenfolge?
Gcharbon
1
Die Jinja2- Vorlage hilft hier, den Pfad zu validieren. Weitere Beispiele in Ansible Docs
DreamUth
10
Beachten Sie, dass auf dem Controller nach Dateien gesucht wird, nicht auf der Fernbedienung.
Fefe
2

Ich finde es ärgerlich und fehleranfällig, viele dieser .stat.existsTypprüfungen durchzuführen. Zum Beispiel benötigen sie besondere Sorgfalt, damit check mode ( --check) funktioniert.

Viele Antworten hier schlagen vor

  • holen und registrieren
  • gelten, wenn der Registerausdruck wahr ist

Manchmal ist dies jedoch ein Codegeruch. Suchen Sie daher immer nach besseren Möglichkeiten, Ansible zu verwenden. Insbesondere die Verwendung des richtigen Moduls bietet viele Vorteile. z.B

- name: install ntpdate
  package:
    name: ntpdate

oder

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

Wenn es jedoch nicht möglich ist, ein Modul zu verwenden, prüfen Sie auch, ob Sie sich registrieren und das Ergebnis einer vorherigen Aufgabe überprüfen können. z.B

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

Beachten Sie das when:aber auch das creates:so --checkkein Fehler aus

Ich erwähne dies, weil diese weniger als idealen Praktiken oft paarweise auftreten, dh kein apt / yum-Paket, so dass wir 1) herunterladen und 2) entpacken müssen

Hoffe das hilft

KCD
quelle
2

Es wurde festgestellt, dass das Aufrufen statlangsam ist und viele Informationen sammelt, die für die Überprüfung der Dateiexistenz nicht erforderlich sind.
Nachdem ich einige Zeit nach einer Lösung gesucht hatte, entdeckte ich folgende Lösung, die viel schneller funktioniert:

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

- debug: msg="Path exists"
  when: file_exists == true
Vladimir Morozov
quelle
1
Bitte beschreiben Sie in Ihrer Antwort, was das Problem war und wie dieses Snippet es lösen wird, um anderen zu helfen, diese Antwort zu verstehen
FZs
1

Sie können das Ansible stat- Modul verwenden, um die Datei zu registrieren, und das wann-Modul, um die Bedingung anzuwenden.

- 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
Asier Gomez
quelle
0

** **.

So überprüfen Sie anhand der when-Bedingung, ob eine Datei in Ansible vorhanden ist

** **.

Unten ist die Ansible-Wiedergabe, die ich verwendet habe, um die Datei zu entfernen, wenn die Datei auf dem Betriebssystemende vorhanden ist.

 - 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

Ich habe die Spielbedingungen wie unten verwendet

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

Sie können je nach Anforderung wahr / falsch angeben

when: splunkresult.stat.exists == false
when: splunkresult.stat.exists == true
namasivayam.cse
quelle
0

Wenn Sie nur sicherstellen möchten, dass eine bestimmte Datei vorhanden ist (z. B. weil sie anders als über ansible erstellt werden soll) und wenn dies nicht der Fall ist, können Sie Folgendes tun:

- 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
Tomáš Pospíšek
quelle
0

Ein Hinweis zu relativen Pfaden als Ergänzung zu den anderen Antworten.

Wenn ich Infrastruktur als Code verwende, verwende ich normalerweise Rollen und Aufgaben, die relative Pfade akzeptieren, insbesondere für Dateien, die in diesen Rollen definiert sind.

Spezielle Variablen wie playbook_dir und role_path sind sehr nützlich, um die absoluten Pfade zu erstellen, die zum Testen der Existenz erforderlich sind.

Federico
quelle