Como verificar se existe um arquivo no Ansible?

128

Eu tenho que verificar se existe um arquivo /etc/. Se o arquivo existir, tenho que pular a tarefa. Aqui está o código que estou usando:

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

Respostas:

207

Você pode primeiro verificar se o arquivo de destino existe ou não e depois tomar uma decisão com base na saída do 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
Arbab Nazar
fonte
1
E se o diretório não existir?
ram4nd
2
Se o diretório não existir, o registro stat_resultterá stat_result.state.existsFalse (e é quando a segunda tarefa for executada). Você pode ver os detalhes do módulo de estatísticas aqui: docs.ansible.com/ansible/stat_module.html
Will
1
quando: stat_result.stat.exists é definido e stat_result.stat.exists
danday74
2
Obrigado por isso. Além disso, se descoberto, você pode escrever: when: stat_result.stat.exists == Falsepara when: not stat_result.stat.existsse quiser ler mais natural.
racl101
1
Você poderia usar "not Foo" em vez de "Foo == False"?
Matthias Urlichs
32

O módulo stat fará isso, assim como obterá muitas outras informações para os arquivos. A partir da documentação de exemplo:

- 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
fonte
Parece que nas versões mais recentes, há um aviso ao usar "comparações de texto completo" como "is" etc em vez de "=", "<", ">" etc.)
Buzut 06/02
24

Isso pode ser alcançado com o módulo stat para ignorar a tarefa quando o arquivo existir.

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

Em geral, você faria isso com o módulo stat . Mas o módulo de comando tem a createsopção que torna isso muito simples:

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

Eu acho que o seu comando de toque é apenas um exemplo? A melhor prática seria não verificar nada e deixar o ansible fazer seu trabalho - com o módulo correto. Portanto, se você quiser garantir que o arquivo exista, use o módulo de arquivo:

- name: make sure file exists
  file:
    path: /etc/file.txt
    state: touch
udondan
fonte
1
state: filenão cria arquivos. Veja docs.ansible.com/ansible/file_module.html
Michael Krupp
2
Eu consideraria o primeiro exemplo nesta resposta a resposta correta para essa pergunta, com base nas circunstâncias específicas da pergunta do usuário, no uso do módulo de comando pelo usuário e nas práticas recomendadas possíveis.
apotek 16/01/19
2
vars:
  mypath: "/etc/file.txt"

tasks:
  - name: checking the file exists
    command: touch file.txt
    when: mypath is not exists
DreamUth
fonte
2
Você não explica sua resposta, e o que when: mypath is not existssignifica neste caso? Não é mypathuma string simples?
gcharbon
1
O modelo Jinja2 ajuda aqui a validar o caminho. Mais exemplos em Ansible Docs
DreamUth 15/08
10
Observe que isso verifica se há arquivos no controlador, não no controle remoto.
Fefe
2

Acho que pode ser irritante e propenso a erros fazer muitas dessas .stat.existsverificações de tipo. Por exemplo, eles exigem cuidados extras para que o modo de verificação ( --check) funcione.

Muitas respostas aqui sugerem

  • obter e registrar
  • aplicar quando a expressão de registro for verdadeira

No entanto, às vezes, esse é um cheiro de código; portanto, sempre procure maneiras melhores de usar o Ansible, especificamente há muitas vantagens em usar o módulo correto. por exemplo

- name: install ntpdate
  package:
    name: ntpdate

ou

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

Mas quando não for possível, use um módulo, investigue também se você pode se registrar e verificar o resultado de uma tarefa anterior. por exemplo

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

Observe o when:mas também o creates:modo --checknão erro

Menciono isso porque muitas vezes essas práticas abaixo do ideal vêm em pares, ou seja, nenhum pacote apt / yum, então temos que 1) baixar e 2) descompactar

Espero que isto ajude

KCD
fonte
2

Descobriu que a chamada staté lenta e coleta muitas informações que não são necessárias para a verificação da existência de arquivos.
Depois de passar algum tempo procurando a solução, descobri a seguinte solução, que funciona muito mais rápido:

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

- debug: msg="Path exists"
  when: file_exists == true
Vladimir Morozov
fonte
1
Por favor, descreva em sua resposta, qual era o problema, e como será esse trecho resolvê-lo, para ajudar os outros a entender esta resposta
FZS
1

Você pode usar o módulo stat Ansible para registrar o arquivo e quando o módulo aplicar a condição.

- 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
fonte
0

**

Como verificar se existe um arquivo no Ansible usando a condição when

**

Abaixo está a reprodução ansible que usei para remover o arquivo quando ele existe no final do sistema operacional.

 - 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

Eu usei a condição de reprodução como abaixo

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

você pode dar verdadeiro / falso com base em sua exigência

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

Se você deseja apenas garantir que um determinado arquivo exista (por exemplo, porque ele deve ser criado de uma maneira diferente da via ansible) e falhar, se não existir, você pode fazer o seguinte:

- 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
fonte
0

Uma observação sobre caminhos relativos para complementar as outras respostas.

Ao fazer a infraestrutura como código, geralmente estou usando funções e tarefas que aceitam caminhos relativos, especialmente para arquivos definidos nessas funções.

Variáveis ​​especiais como playbook_dir e role_path são muito úteis para criar os caminhos absolutos necessários para testar a existência.

Federico
fonte