Come verificare se un file esiste in Ansible?


128

Devo controllare se esiste un file in /etc/. Se il file esiste, devo saltare l'attività. Ecco il codice che sto usando:

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

Risposte:


209

Puoi prima verificare che il file di destinazione esista o meno e quindi prendere una decisione in base all'output del suo risultato:

    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
E se la directory non esiste?
ram4nd

2
Se la directory non esiste, il registro stat_resultavrà un valore stat_result.state.existsFalse (ed è allora che viene eseguita la seconda attività). Puoi vedere i dettagli del modulo stat qui: docs.ansible.com/ansible/stat_module.html
Will

1
quando: stat_result.stat.exists è definito e stat_result.stat.exists
danday74

2
Grazie per questo. Inoltre, se scoperto puoi scrivere: when: stat_result.stat.exists == Falsea when: not stat_result.stat.existsse vuoi che legga in modo più naturale.
racl101

1
Per favore, useresti "not Foo" invece di "Foo == False"?
Matthias Urlichs

32

Il modulo stat lo farà e otterrà molte altre informazioni per i file. Dalla documentazione di esempio:

- 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

Sembra che nelle ultime versioni sia presente un avviso quando si utilizzano "confronti di testo completo" come "è" ecc. Invece di "=", "<", ">" ecc.
Buzut

24

Ciò può essere ottenuto con il modulo stat per saltare l'attività quando il file esiste.

- 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

In generale lo faresti con il modulo stat . Ma il modulo di comando ha l' createsopzione che lo rende molto semplice:

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

Immagino che il tuo comando tattile sia solo un esempio? La migliore pratica sarebbe quella di non controllare nulla e lasciare che ansible faccia il suo lavoro - con il modulo corretto. Quindi, se vuoi assicurarti che il file esista, dovresti usare il modulo file:

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

1
state: filenon crea file. Vedi docs.ansible.com/ansible/file_module.html
Michael Krupp

2
Considero il primo esempio in questa risposta la risposta giusta per questa domanda, in base alle circostanze specifiche della domanda dell'utente, all'uso da parte dell'utente del modulo di comando e alle migliori pratiche ansible.
apotek

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

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

2
Non spieghi la tua risposta, e cosa when: mypath is not existssignifica in questo caso? Non è mypathuna semplice stringa?
gcharbon

1
Il modello Jinja2 aiuta qui a convalidare il percorso. Altri esempi in Ansible Docs
DreamUth

10
Nota che questo controlla i file sul controller, non sul telecomando.
fefe

2

Trovo che possa essere fastidioso e soggetto a errori eseguire molti di questi .stat.existscontrolli di tipo. Ad esempio richiedono un'attenzione particolare per far funzionare la modalità check ( --check).

Molte risposte qui suggeriscono

  • ottenere e registrarsi
  • applicare quando l'espressione del registro è vera

Tuttavia, a volte questo è un odore di codice, quindi cerca sempre modi migliori per usare Ansible, in particolare ci sono molti vantaggi nell'usare il modulo corretto. per esempio

- name: install ntpdate
  package:
    name: ntpdate

o

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

Ma quando non è possibile utilizzare un modulo, verifica anche se puoi registrarti e controllare il risultato di un'attività precedente. per esempio

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

Notare il when:ma anche creates:così --checknon si verificano errori

Lo dico perché spesso queste pratiche tutt'altro che ideali vengono in coppia, cioè nessun pacchetto apt / yum quindi dobbiamo 1) scaricare e 2) decomprimere

Spero che questo ti aiuti


2

Ho scoperto che la chiamata statè lenta e raccoglie molte informazioni non necessarie per il controllo dell'esistenza dei file.
Dopo aver passato un po 'di tempo a cercare una soluzione, ho scoperto la seguente soluzione, che funziona molto più velocemente:

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

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

1
Descrivi nella tua risposta qual era il problema e come lo risolverà questo frammento per aiutare gli altri a capire questa risposta
FZ

1

È possibile utilizzare il modulo stat Ansible per registrare il file e il modulo when per applicare la condizione.

- 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

**

Come verificare se un file esiste in Ansible utilizzando la condizione when

**

Di seguito è riportata la riproduzione ansible che ho utilizzato per rimuovere il file quando il file esiste nel sistema operativo.

 - 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

Ho usato la condizione di gioco come sotto

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

puoi dare vero / falso in base alle tue esigenze

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

0

Se vuoi solo assicurarti che un determinato file esista (ad es. Perché dovrebbe essere creato in un modo diverso rispetto a ansible) e fallire in caso contrario, puoi farlo:

- 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

Una nota sui percorsi relativi per completare le altre risposte.

Quando si esegue l'infrastruttura come codice, di solito si utilizzano ruoli e attività che accettano percorsi relativi, specialmente per i file definiti in quei ruoli.

Variabili speciali come playbook_dir e role_path sono molto utili per creare i percorsi assoluti necessari per testare l'esistenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.