/etc/
- name: checking the file exists command: touch file.txt when: $(! -s /etc/file.txt)
一般来说,你会用统计模块。但是命令模块有creates选项,这使得这非常简单:
creates
- name: touch file command: touch /etc/file.txt args: creates: /etc/file.txt
我猜你的触摸命令只是一个例子?最好的做法是不检查任何东西,让ansible用正确的模块完成它的工作。所以如果你想确保文件存在,你可以使用file模块:
- name: make sure file exists file: path: /etc/file.txt state: touch
统计模块将完成此操作,并为文件获取许多其他信息。从示例文档中:
- 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
您可以首先检查目标文件是否存在,然后根据其结果的输出做出决定:
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
这可以通过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
vars: mypath: "/etc/file.txt" tasks: - name: checking the file exists command: touch file.txt when: mypath is not exists
我发现做很多这样的.stat.exists类型检查是很烦人且容易出错的。例如,它们需要额外的注意才能使检查模式(--check)工作。
.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不会出错
when:
creates:
我之所以提到这一点,是因为这些不太理想的做法通常是成对出现的,即没有apt/yum包,所以我们必须1)下载和2)解压缩
希望这能有所帮助
发现调用stat很慢,并且收集了很多文件存在性检查不需要的信息。 在花了一些时间寻找解决方案后,我发现了以下解决方案,它工作得更快:
stat
- raw: test -e /path/to/something && echo -n true || echo -n false register: file_exists - debug: msg="Path exists" when: file_exists.stdout == "true"
下面是ansible play,我用来删除文件,如果文件存在于操作系统端。
- 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
你可以使用Ansible 统计模块来注册文件,当模块应用条件。
- 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
关于相对路径的注释,以补充其他答案。
当把基础设施作为代码使用时,我通常使用接受相对路径的角色和任务,特别是对于在这些角色中定义的文件。
像playbook_dir和role_path这样的特殊变量对于创建测试存在性所需的绝对路径非常有用。
我使用这段代码,它可以很好地用于文件夹和文件。只要确保文件夹名称后没有尾随空格即可。如果文件夹存在,则file_exists。Stdout将是“true”;否则它将只是一个空字符串""
- name: check filesystem existence shell: if [[ -d "/folder_name" ]]; then echo "true"; fi register: file_exists - name: debug data debug: msg: "Folder exists" when: file_exists.stdout == "true"
您可以使用shell命令检查文件是否存在
- set_fact: file: "/tmp/test_file" - name: check file exists shell: "ls \{\{ file }}" register: file_path ignore_errors: true - name: create file if don't exist shell: "touch \{\{ file }}" when: file_path.rc != 0