Comment vérifier si un fichier existe dans Ansible?

128

Je dois vérifier si un fichier existe au format /etc/. Si le fichier existe, je dois sauter la tâche. Voici le code que j'utilise:

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

Réponses:

209

Vous pouvez d'abord vérifier que le fichier de destination existe ou non, puis prendre une décision en fonction de la sortie de son résultat:

    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
la source
1
Que faire si le répertoire n'existe pas?
ram4nd
2
Si le répertoire n'existe pas, le registre stat_resultaura la valeur stat_result.state.existsFalse (et c'est à ce moment-là que la deuxième tâche s'exécute). Vous pouvez voir les détails du module de statistiques ici: docs.ansible.com/ansible/stat_module.html
Will
1
quand: stat_result.stat.exists est défini et stat_result.stat.exists
danday74
2
Merci pour cela. De plus, si vous le découvrez, vous pouvez écrire: when: stat_result.stat.exists == Falseà when: not stat_result.stat.existssi vous le souhaitez pour une lecture plus naturelle.
racl101
1
Pourriez-vous s'il vous plaît utiliser "not Foo" au lieu de "Foo == False"?
Matthias Urlichs
32

Le module stat fera cela et obtiendra de nombreuses autres informations sur les fichiers. À partir de l'exemple de documentation:

- 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
la source
On dirait que dans les dernières versions, il y a un avertissement lors de l'utilisation de "comparaisons de texte intégral" comme "est" etc au lieu de "=", "<", ">" etc.
Buzut le
24

Cela peut être réalisé avec le module stat pour sauter la tâche lorsque le fichier existe.

- 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
la source
16

En général, vous feriez cela avec le module stat . Mais le module de commande a l' createsoption qui rend cela très simple:

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

Je suppose que votre commande tactile n'est qu'un exemple? La meilleure pratique serait de ne rien vérifier du tout et de laisser ansible faire son travail - avec le bon module. Donc, si vous voulez vous assurer que le fichier existe, vous utiliserez le module de fichiers:

- name: make sure file exists
  file:
    path: /etc/file.txt
    state: touch
udondan
la source
1
state: filene crée pas de fichiers. Voir docs.ansible.com/ansible/file_module.html
Michael Krupp
2
Je considérerais le premier exemple de cette réponse comme la bonne réponse à cette question, en fonction des circonstances spécifiques de la question de l'utilisateur, de l'utilisation du module de commande par l'utilisateur et des meilleures pratiques possibles.
apotek
2
vars:
  mypath: "/etc/file.txt"

tasks:
  - name: checking the file exists
    command: touch file.txt
    when: mypath is not exists
DreamUth
la source
2
Vous n'expliquez pas votre réponse, et qu'est-ce que cela when: mypath is not existssignifie dans ce cas? N'est-ce pas mypathune simple chaîne?
gcharbon
1
Le modèle Jinja2 aide ici à valider le chemin. Plus d'exemples dans Ansible Docs
DreamUth
10
Notez que cela vérifie les fichiers sur le contrôleur, pas sur la télécommande.
fefe
2

Je trouve que faire beaucoup de ces .stat.existsvérifications de type peut être ennuyeux et sujet aux erreurs . Par exemple, ils nécessitent une attention particulière pour faire fonctionner le mode de vérification ( --check).

De nombreuses réponses suggèrent ici

  • obtenir et s'inscrire
  • appliquer lorsque l'expression de registre est vraie

Cependant, il s'agit parfois d'une odeur de code, alors cherchez toujours de meilleures façons d'utiliser Ansible, en particulier, il y a de nombreux avantages à utiliser le bon module. par exemple

- name: install ntpdate
  package:
    name: ntpdate

ou

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

Mais quand ce n'est pas possible, utilisez un module, cherchez également si vous pouvez vous inscrire et vérifier le résultat d'une tâche précédente. par exemple

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

Notez le when:mais aussi le creates:donc --checkne fait pas d'erreur

Je mentionne cela parce que souvent ces pratiques moins qu'idéales viennent par paires, c'est-à-dire pas de package apt / yum, nous devons donc 1) télécharger et 2) décompresser

J'espère que cela t'aides

KCD
la source
2

Découvert que l'appel statest lent et recueille beaucoup d'informations qui ne sont pas nécessaires pour la vérification de l'existence des fichiers.
Après avoir passé du temps à chercher une solution, j'ai découvert la solution suivante, qui fonctionne beaucoup plus rapidement:

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

- debug: msg="Path exists"
  when: file_exists == true
Vladimir Morozov
la source
1
Veuillez décrire dans votre réponse, quel était le problème et comment cet extrait de code le résoudra-t-il, pour aider les autres à comprendre cette réponse
FZs
1

Vous pouvez utiliser le module Ansible stat pour enregistrer le fichier et le module When pour appliquer la condition.

- 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
la source
0

**

Comment vérifier si un fichier existe dans Ansible en utilisant la condition When

**

Vous trouverez ci-dessous la lecture ansible que j'ai utilisée pour supprimer le fichier lorsque le fichier existe à la fin du système d'exploitation.

 - 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

J'ai utilisé la condition de jeu comme ci-dessous

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

vous pouvez donner vrai / faux en fonction de vos besoins

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

Si vous voulez simplement vous assurer qu'un certain fichier existe (par exemple, car il devrait être créé d'une manière différente de celle via ansible) et échouer si ce n'est pas le cas, vous pouvez le faire:

- 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
la source
0

Une note sur les chemins relatifs pour compléter les autres réponses.

Lorsque j'utilise une infrastructure en tant que code, j'utilise généralement des rôles et des tâches qui acceptent des chemins relatifs, en particulier pour les fichiers définis dans ces rôles.

Des variables spéciales comme playbook_dir et role_path sont très utiles pour créer les chemins absolus nécessaires pour tester l'existence.

Federico
la source