Reputation: 2217
I have to check whether a file exists in /etc/
. If the file exists then I have to skip the task.
Here is the code I am using:
- name: checking the file exists
command: touch file.txt
when: $(! -s /etc/file.txt)
Upvotes: 220
Views: 429136
Reputation: 20719
The stat module will do this as well as obtain a lot of other information for files. From the example documentation:
- 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
Upvotes: 51
Reputation: 491
This can be achieved with the stat module to skip the task when file exists.
- 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
Upvotes: 39
Reputation: 23791
You can first check that the destination file exists or not and then make a decision based on the output of its result:
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
Upvotes: 391
Reputation: 41
Like described in the documentation you can check if a file ore directory does exist in the when statement like:
- name: Check file exists
debug:
msg: File exists
when: "'/my/path' is file"
This is not really well documented and the most google searches points to the solution with the stat module.
To check if the path exists ore not you can use:
- debug:
msg: Path not exists
when: '/my/path' is not exists
Upvotes: 4
Reputation: 59989
In general you would do this with the stat module. But the command module has the creates
option which makes this very simple:
- name: touch file
command: touch /etc/file.txt
args:
creates: /etc/file.txt
I guess your touch command is just an example? Best practice would be to not check anything at all and let ansible do its job - with the correct module. So if you want to ensure the file exists you would use the file module:
- name: make sure file exists
file:
path: /etc/file.txt
state: touch
Upvotes: 21
Reputation: 377
Below is the ansible play which i used to remove the file if the file exists on OS end.
- 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
I have used play condition as like below
when: splunkresult.stat.exists == true --> Remove the file
you can give true/false based on your requirement
when: splunkresult.stat.exists == false
when: splunkresult.stat.exists == true
Upvotes: 3
Reputation: 99
Discovered that calling stat
is slow and collects a lot of info that is not required for file existence check.
After spending some time searching for solution, i discovered following solution, which works much faster:
- raw: test -e /path/to/something && echo -n true || echo -n false
register: file_exists
- debug: msg="Path exists"
when: file_exists.stdout == "true"
Upvotes: 7
Reputation: 1315
You can use shell commands to check if file exists
- 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
Upvotes: 0
Reputation: 29
I use this code and it works fine for folders and files. Just make sure there is no trailing spaces after the folder name. If folder exists , the file_exists.stdout will be "true" otherwise it will just be an empty string ""
- 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"
Upvotes: 1
Reputation: 1731
A note on relative paths to complement the other answers.
When doing infrastructure as code I'm usually using roles and tasks that accept relative paths, specially for files defined in those roles.
Special variables like playbook_dir and role_path are very useful to create the absolute paths needed to test for existence.
Upvotes: 0
Reputation: 6578
You can use Ansible stat module to register the file, and when module to apply the condition.
- 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
Upvotes: 3
Reputation: 10281
I find it can be annoying and error prone to do a lot of these .stat.exists
type checks. For example they require extra care to get check mode (--check
) working.
Many answers here suggest
However, sometimes this is a code smell so always look for better ways to use Ansible, specifically there are many advantages to using the correct module. e.g.
- name: install ntpdate
package:
name: ntpdate
or
- file:
path: /etc/file.txt
owner: root
group: root
mode: 0644
But when it is not possible use one module, also investigate if you can register and check the result of a previous task. e.g.
# 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'
Note the when:
but also the creates:
so --check
doesn't error out
I mention this because often these less-than-ideal practices come in pairs i.e. no apt/yum package so we have to 1) download and 2) unzip
Hope this helps
Upvotes: 2
Reputation: 132
vars:
mypath: "/etc/file.txt"
tasks:
- name: checking the file exists
command: touch file.txt
when: mypath is not exists
Upvotes: 0