Làm cách nào để kiểm tra xem tệp có tồn tại trong Ansible không?


128

Tôi phải kiểm tra xem tệp có tồn tại trong không /etc/. Nếu tệp tồn tại thì tôi phải bỏ qua tác vụ. Đây là mã tôi đang sử dụng:

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

Câu trả lời:


208

Trước tiên, bạn có thể kiểm tra xem tệp đích có tồn tại hay không và sau đó đưa ra quyết định dựa trên kết quả đầu ra của nó:

    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
Nếu thư mục không tồn tại thì sao?
ram4nd

2
Nếu thư mục không tồn tại, thì thanh ghi stat_resultsẽ có giá stat_result.state.existstrị Sai (và đó là khi tác vụ thứ hai chạy). Bạn có thể xem chi tiết của mô-đun thống kê tại đây: docs.ansible.com/ansible/stat_module.html
Sẽ

1
khi: stat_result.stat.exists được xác định và stat_result.stat.exists
danday74

2
Cảm ơn vì điều đó. Ngoài ra, nếu phát hiện ra bạn có thể viết: when: stat_result.stat.exists == Falseđể when: not stat_result.stat.existsnếu bạn muốn nó để đọc tự nhiên hơn.
racl101 27/07/18

1
Bạn có vui lòng sử dụng "not Foo" thay vì "Foo == False" không?
Matthias Urlichs 24/09/19

32

Các stat mô-đun sẽ làm được điều này cũng như có được rất nhiều thông tin khác cho các tập tin. Từ tài liệu ví dụ:

- 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

Có vẻ như trong các phiên bản mới nhất, có một cảnh báo khi sử dụng "so sánh toàn văn" như "is" etc thay vì "=", "<", ">", v.v.
Buzut

24

Điều này có thể đạt được với mô-đun stat để bỏ qua tác vụ khi tệp tồn tại.

- 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

Nói chung, bạn sẽ làm điều này với mô-đun stat . Nhưng mô-đun lệnhcreatestùy chọn làm cho việc này rất đơn giản:

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

Tôi đoán lệnh cảm ứng của bạn chỉ là một ví dụ? Phương pháp hay nhất là không kiểm tra bất cứ thứ gì và để ansible thực hiện công việc của nó - với đúng mô-đun. Vì vậy, nếu bạn muốn đảm bảo tệp tồn tại, bạn sẽ sử dụng mô-đun tệp:

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

1
state: filekhông tạo tệp. Xem docs.ansible.com/ansible/file_module.html
Michael Krupp

2
Tôi sẽ coi ví dụ đầu tiên trong câu trả lời này là câu trả lời đúng cho câu hỏi này, dựa trên các trường hợp cụ thể của câu hỏi của người dùng, việc sử dụng mô-đun lệnh của người dùng và các phương pháp hay nhất có thể trả lời được.
apotek

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

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

2
Bạn không giải thích câu trả lời của mình, và điều gì có when: mypath is not existsnghĩa là trong trường hợp này? Không phải là mypathmột chuỗi đơn giản?
gcharbon

1
Mẫu Jinja2 giúp xác thực đường dẫn ở đây. Các ví dụ khác trong Ansible Docs
DreamUth

10
Lưu ý rằng điều này sẽ kiểm tra các tệp trên bộ điều khiển, không phải điều khiển từ xa.
fefe

2

Tôi thấy nó có thể gây phiền nhiễu và dễ xảy ra lỗi khi thực hiện nhiều .stat.existskiểm tra kiểu này . Ví dụ, họ yêu cầu cẩn thận hơn để chế độ kiểm tra ( --check) hoạt động.

Nhiều câu trả lời ở đây gợi ý

  • lấy và đăng ký
  • áp dụng khi biểu thức đăng ký là đúng

Tuy nhiên, đôi khi đây là một mùi mã vì vậy hãy luôn tìm cách tốt hơn để sử dụng Ansible, cụ thể là có nhiều lợi thế khi sử dụng đúng mô-đun. ví dụ

- name: install ntpdate
  package:
    name: ntpdate

hoặc là

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

Nhưng khi không thể sử dụng một mô-đun, hãy điều tra xem bạn có thể đăng ký và kiểm tra kết quả của nhiệm vụ trước đó hay không. ví dụ

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

Chú ý các when:mà còn creates:để --checkkhông lôi ra

Tôi đề cập đến điều này bởi vì thường những phương pháp ít lý tưởng hơn này đi theo cặp tức là không có gói apt / yum, vì vậy chúng tôi phải 1) tải xuống và 2) giải nén

Hi vọng điêu nay co ich


2

Phát hiện ra rằng cuộc gọi statchậm và thu thập nhiều thông tin không cần thiết để kiểm tra sự tồn tại của tệp.
Sau khi dành thời gian tìm kiếm giải pháp, tôi đã phát hiện ra giải pháp sau, giải pháp này hoạt động nhanh hơn nhiều:

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

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

1
Vui lòng mô tả trong câu trả lời của bạn, vấn đề là gì và đoạn mã này sẽ giải quyết nó như thế nào, để giúp những người khác hiểu câu trả lời này
FZs

1

Bạn có thể sử dụng mô-đun Ansible stat để đăng ký tệp và khi mô-đun áp dụng điều kiệ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ách kiểm tra xem tệp có tồn tại trong Ansible hay không bằng cách sử dụng điều kiện when

**

Dưới đây là cách chơi không thể xóa được mà tôi đã sử dụng để xóa tệp khi tệp tồn tại trong phần cuối của hệ điều hành.

 - 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

Tôi đã sử dụng điều kiện chơi như dưới đây

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

bạn có thể đưa ra true / false dựa trên yêu cầu của bạn

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

0

Nếu bạn chỉ muốn đảm bảo rằng một tệp nhất định tồn tại (f.ex. bởi vì nó phải được tạo theo một cách khác chứ không phải thông qua ansible) và không thành công nếu không, thì bạn có thể làm điều này:

- 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

Một ghi chú về các đường dẫn tương đối để bổ sung cho các câu trả lời khác.

Khi làm cơ sở hạ tầng dưới dạng mã, tôi thường sử dụng các vai trò và nhiệm vụ chấp nhận các đường dẫn tương đối, đặc biệt cho các tệp được xác định trong các vai trò đó.

Các biến đặc biệt như playbook_dir và role_path rất hữu ích để tạo các đường dẫn tuyệt đối cần thiết để kiểm tra sự tồn tại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.