วิธีตรวจสอบว่ามีไฟล์อยู่ใน Ansible หรือไม่?


128

ฉันต้องตรวจสอบว่ามีไฟล์อยู่ในไฟล์/etc/. ถ้าไฟล์มีอยู่ฉันต้องข้ามงาน นี่คือรหัสที่ฉันใช้:

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

คำตอบ:


209

ก่อนอื่นคุณสามารถตรวจสอบว่ามีไฟล์ปลายทางอยู่หรือไม่จากนั้นจึงตัดสินใจตามผลลัพธ์ของผลลัพธ์:

    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
จะเกิดอะไรขึ้นถ้าไม่มีไดเร็กทอรี
ram4nd

2
หากไม่มีไดเร็กทอรีการลงทะเบียนstat_resultจะมีstat_result.state.existsFalse (และนั่นคือเมื่อภารกิจที่สองทำงาน) คุณสามารถดูรายละเอียดของโมดูลสถิติได้ที่นี่: docs.ansible.com/ansible/stat_module.html
จะ

1
เมื่อ: stat_result.stat.exists ถูกกำหนดและ stat_result.stat.exists
danday74

2
ขอบคุณสำหรับสิ่งนี้. นอกจากนี้หากพบคุณสามารถเขียน: when: stat_result.stat.exists == Falseถึงwhen: not stat_result.stat.existsถ้าคุณต้องการให้อ่านเป็นธรรมชาติมากขึ้น
racl101

1
คุณช่วยใช้ "not Foo" แทน "Foo == False" ได้ไหม
Matthias Urlichs

32

สถิติโมดูลจะทำเช่นนี้เช่นเดียวกับการได้รับข้อมูลจำนวนมากอื่น ๆ สำหรับไฟล์ จากเอกสารตัวอย่าง:

- 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

ดูเหมือนว่าในเวอร์ชันล่าสุดจะมีคำเตือนเมื่อใช้ "การเปรียบเทียบข้อความแบบเต็ม" เช่น "is" etc แทน "=", "<", ">" เป็นต้น
Buzut

24

สิ่งนี้สามารถทำได้ด้วยโมดูล stat เพื่อข้ามงานเมื่อมีไฟล์อยู่

- 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

โดยทั่วไปคุณจะทำเช่นนี้กับโมดูลสถิติ แต่โมดูลคำสั่งมีcreatesตัวเลือกที่ทำให้ง่ายมาก:

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

ฉันเดาว่าคำสั่งสัมผัสของคุณเป็นเพียงตัวอย่าง? แนวทางปฏิบัติที่ดีที่สุดคือการไม่ตรวจสอบสิ่งใด ๆ เลยและปล่อยให้ตอบได้ทำงานด้วยโมดูลที่ถูกต้อง ดังนั้นหากคุณต้องการให้แน่ใจว่ามีไฟล์อยู่คุณจะใช้โมดูลไฟล์:

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

1
state: fileไม่สร้างไฟล์ ดูdocs.ansible.com/ansible/file_module.html
Michael Krupp

2
ฉันจะพิจารณาตัวอย่างแรกในคำตอบนี้เป็นคำตอบที่ถูกต้องสำหรับคำถามนี้โดยพิจารณาจากสถานการณ์เฉพาะของคำถามของผู้ใช้การใช้โมดูลคำสั่งของผู้ใช้และแนวทางปฏิบัติที่ดีที่สุดที่ตอบได้
apotek

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

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

2
คุณไม่ได้อธิบายคำตอบของคุณและwhen: mypath is not existsในกรณีนี้หมายความว่าอย่างไร? mypathสตริงธรรมดาไม่ใช่เหรอ
gcharbon

1
เทมเพลตJinja2ช่วยในการตรวจสอบเส้นทาง ตัวอย่างเพิ่มเติมใน
Ansible

10
โปรดทราบว่าสิ่งนี้จะตรวจหาไฟล์บนคอนโทรลเลอร์ไม่ใช่รีโมต
61

2

ฉันพบว่าการ.stat.existsตรวจสอบประเภทนี้อาจเป็นเรื่องที่น่ารำคาญและมีข้อผิดพลาดบ่อยครั้ง ตัวอย่างเช่นพวกเขาต้องการความระมัดระวังเป็นพิเศษเพื่อให้โหมดตรวจสอบ ( --check) ทำงานได้

คำตอบมากมายที่นี่แนะนำ

  • รับและลงทะเบียน
  • นำไปใช้เมื่อนิพจน์การลงทะเบียนเป็นจริง

อย่างไรก็ตามบางครั้งนี่เป็นกลิ่นรหัสดังนั้นควรมองหาวิธีที่ดีกว่าในการใช้ Ansible โดยเฉพาะมีข้อดีหลายประการในการใช้โมดูลที่ถูกต้อง เช่น

- name: install ntpdate
  package:
    name: ntpdate

หรือ

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

แต่เมื่อเป็นไปไม่ได้ให้ใช้โมดูลเดียวให้ตรวจสอบด้วยว่าคุณสามารถลงทะเบียนและตรวจสอบผลลัพธ์ของงานก่อนหน้านี้ได้หรือไม่ เช่น

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

ทราบwhen:แต่ยังcreates:เพื่อให้--checkไม่เกิดข้อผิดพลาดออก

ฉันพูดถึงสิ่งนี้เพราะบ่อยครั้งการปฏิบัติที่น้อยกว่าอุดมคติเหล่านี้มาเป็นคู่ ๆ เช่นไม่มีแพ็คเกจ apt / yum ดังนั้นเราต้อง 1) ดาวน์โหลดและ 2) เปิดเครื่องรูด

หวังว่านี่จะช่วยได้


2

ค้นพบว่าการโทรstatช้าและรวบรวมข้อมูลจำนวนมากที่ไม่จำเป็นสำหรับการตรวจสอบการมีอยู่ของไฟล์
หลังจากใช้เวลาค้นหาโซลูชันฉันค้นพบวิธีแก้ปัญหาต่อไปนี้ซึ่งทำงานได้เร็วขึ้นมาก:

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

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

1
โปรดอธิบายในคำตอบของคุณว่าปัญหาคืออะไรและตัวอย่างข้อมูลนี้จะแก้ปัญหาอย่างไรเพื่อช่วยให้ผู้อื่นเข้าใจคำตอบนี้
FZs

1

คุณสามารถใช้โมดูลAnsible statเพื่อลงทะเบียนไฟล์และเมื่อโมดูลใช้เงื่อนไข

- 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

**

วิธีตรวจสอบว่ามีไฟล์อยู่ใน Ansible หรือไม่โดยใช้เมื่อเงื่อนไข

**

ด้านล่างนี้คือการเล่นที่ตอบได้ที่ฉันใช้เพื่อลบไฟล์เมื่อไฟล์มีอยู่ในระบบปฏิบัติการสิ้นสุด

 - 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

ฉันได้ใช้สภาพการเล่นเช่นเดียวกับด้านล่าง

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

คุณสามารถให้จริง / เท็จตามความต้องการของคุณ

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

0

หากคุณต้องการตรวจสอบให้แน่ใจว่ามีไฟล์บางไฟล์อยู่ (f.ex. เนื่องจากไฟล์ดังกล่าวถูกสร้างขึ้นด้วยวิธีที่แตกต่างจากทาง ansible) และล้มเหลวหากไม่เป็นเช่นนั้นคุณสามารถทำได้:

- 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

หมายเหตุเกี่ยวกับเส้นทางสัมพัทธ์เพื่อเสริมคำตอบอื่น ๆ

เมื่อทำโครงสร้างพื้นฐานเป็นรหัสฉันมักจะใช้บทบาทและงานที่ยอมรับเส้นทางสัมพัทธ์โดยเฉพาะสำหรับไฟล์ที่กำหนดไว้ในบทบาทเหล่านั้น

ตัวแปรพิเศษเช่น playbook_dir และ role_path มีประโยชน์มากในการสร้างเส้นทางสัมบูรณ์ที่จำเป็นในการทดสอบการมีอยู่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.