¿Cómo verificar si existe un archivo en Ansible?


128

Tengo que verificar si existe un archivo en /etc/. Si el archivo existe, entonces tengo que omitir la tarea. Aquí está el código que estoy usando:

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

Respuestas:


207

Primero puede verificar si el archivo de destino existe o no y luego tomar una decisión en función de la salida de su resultado:

    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
¿Qué pasa si el directorio no existe?
ram4nd

2
Si el directorio no existe, entonces el registro stat_resulttendrá un valor stat_result.state.existsFalso (y es entonces cuando se ejecuta la segunda tarea). Puede ver los detalles del módulo de estadísticas aquí: docs.ansible.com/ansible/stat_module.html
Será el

1
cuándo: stat_result.stat.exists está definido y stat_result.stat.exists
danday74

2
Gracias por esto. Además, si lo encuentra, puede escribir: when: stat_result.stat.exists == Falsea when: not stat_result.stat.existssi desea que se lea de forma más natural.
racl101

1
¿Podría usar "no Foo" en lugar de "Foo == False"?
Matthias Urlichs

32

El módulo de estadísticas hará esto y también obtendrá mucha otra información para los archivos. De la documentación de ejemplo:

- 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

Parece que en las últimas versiones, hay una advertencia al usar "comparaciones de texto completo" como "is", etc. en lugar de "=", "<", ">" etc.
Buzut

24

Esto se puede lograr con el módulo de estadísticas para omitir la tarea cuando existe un archivo.

- 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

En general, haría esto con el módulo de estadísticas . Pero el módulo de comando tiene la createsopción que lo hace muy simple:

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

¿Supongo que tu comando táctil es solo un ejemplo? La mejor práctica sería no verificar nada y dejar que Ansible haga su trabajo, con el módulo correcto. Entonces, si desea asegurarse de que el archivo existe, usaría el módulo de archivo:

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

1
state: fileNo crea archivos. Ver docs.ansible.com/ansible/file_module.html
Michael Krupp

2
Consideraría el primer ejemplo en esta respuesta como la respuesta correcta para esta pregunta, en función de las circunstancias específicas de la pregunta del usuario, el uso del módulo de comando por parte del usuario y las mejores prácticas disponibles.
Apotek

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

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

2
No explicas tu respuesta, y ¿qué when: mypath is not existssignifica en este caso? ¿No es mypathuna cadena simple?
gcharbon

1
La plantilla Jinja2 ayuda aquí a validar la ruta. Más ejemplos en
Doc.

10
Tenga en cuenta que esto busca archivos en el controlador, no en el control remoto.
fefe

2

Creo que puede ser molesto y propenso a errores hacer muchas de estas .stat.existscomprobaciones de tipo. Por ejemplo, requieren un cuidado especial para que el modo de verificación ( --check) funcione.

Muchas respuestas aquí sugieren

  • obtener y registrarse
  • aplicar cuando la expresión de registro es verdadera

Sin embargo, a veces este es un olor a código, así que siempre busque mejores formas de usar Ansible, específicamente existen muchas ventajas al usar el módulo correcto. p.ej

- name: install ntpdate
  package:
    name: ntpdate

o

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

Pero cuando no sea posible, use un módulo, también investigue si puede registrarse y verificar el resultado de una tarea anterior. p.ej

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

Tenga en cuenta la when:sino también el creates:modo --checkno fuera error

Menciono esto porque a menudo estas prácticas menos que ideales vienen en pares, es decir, sin paquete apt / yum, por lo que tenemos que 1) descargar y 2) descomprimir

Espero que esto ayude


2

Descubrió que las llamadas statson lentas y recopilan mucha información que no es necesaria para la verificación de existencia de archivos.
Después de pasar algún tiempo buscando una solución, descubrí la siguiente solución, que funciona mucho más rápido:

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

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

1
Describa en su respuesta, cuál fue el problema y cómo lo resolverá este fragmento, para ayudar a otros a entender esta respuesta
FZs

1

Puede usar el módulo estadístico Ansible para registrar el archivo y cuándo el módulo aplicará la condición.

- 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

** **

Cómo verificar si existe un archivo en Ansible usando cuando condición

** **

A continuación se muestra la reproducción ansible que utilicé para eliminar el archivo cuando el archivo existe en el sistema operativo final.

 - 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

He usado la condición de juego como a continuación

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

puede dar verdadero / falso según su requerimiento

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

0

Si solo desea asegurarse de que existe un determinado archivo (por ejemplo, porque debe crearse de una manera diferente a la de ansible) y falla si no es así, puede hacer esto:

- 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 sobre caminos relativos para complementar las otras respuestas.

Cuando hago infraestructura como código, generalmente uso roles y tareas que aceptan rutas relativas, especialmente para los archivos definidos en esos roles.

Las variables especiales como playbook_dir y role_path son muy útiles para crear las rutas absolutas necesarias para probar la existencia.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.