Check if a file exists with Bash
December 28, 2020 ‐ 4 min read
In your Bash script you'll have to deal with files at some point. So knowing for sure whether a file exists or not comes in handy at some point. You can test for these conditions in an if statement luckily.
Normally, in Bash, the preferred way to test this condition is by using double square brackets([[ … ]]
), which is the improved version of the single square brackets ([ … ]
). Do keep in mind however that the double square brackets might not be available in other shells. So for portability you might want to prefer single square brackets over the double ones.
To test for the existence of a file we can use the -f
file test operator. The -f
operator returns true if the file for the specified path exists and is a actual file, so not a directory.
In the script below an example is shown, in which a file is created first and secondly the existence is validated.
#!/bin/bash
# 1. We create a file
touch ~/dirty_secrets.txt
# 2. Check whether the file exist
if [[ -f "$HOME/dirty_secrets.txt" ]]; then
echo "You have dirty secrets"
fi
And now run the script.
$ ./dirty-secrets
You have dirty secrets
There are a couple things that the -f
operator does and doesn’t take into account. It does check if the specified file is actually a file. So if the specified path is an existing directory it still returns false. It doesn't check whether the file is a symlink or not. So if the specified path is a path to a symlink, it does return true.
Test if a file doesn't exist
For checking if a file is not existing we can do something similar. In order to check whether a file doesn’t exist we negate the condition with an exclamation mark.
#!/bin/bash
# 1. Now we remove the file
rm ~/dirty_secrets.txt
# 2. And check whether the file exist
if [[ ! -f "$HOME/dirty_secrets.txt" ]]; then
echo "Good boy, no dirty secrets"
fi
Lets see the result of the updated version of the script now.
$ ./dirty-secrets
Good boy, no dirty secrets
Create file if it doesn't exist
A more likely use-case is that you want to create a file if it doesn’t exist yet. With a small modification we can do just that.
We can create the file by using the touch
command.
#!/bin/bash
# 1. Store the files path in a variable
file="$HOME/dirty_secrets.txt"
# 2. Create a file if it doesn't exist
if [[ ! -f $file ]]; then
touch $file
echo "Created file '$file'"
fi
Lets see what happens when we run this version of the script.
$ ./dirty-secrets
Created file '/home/koen/dirty_secrets.txt'
Test if a folder exist
Testing for the existence of a directory is the same but uses a different operator. Where we used -f
to check for the existence of a file, we use -d
for directories.
#!/bin/bash
# 1. We create a file
mkdir ~/dirty_secrets
# 2. Check whether the directory exist
if [[ -d "$HOME/dirty_secrets" ]]; then
echo "You have dirty secrets"
fi
When we run the script we get the following output.
$ ./dirty-secrets
You have dirty secrets
Check multiple files at once
Checking for multiple files at once can be done as well. In order to do so you combine the conditions with &&
.
if [[ -f "$HOME/dirty_secrets/mine.txt" ]] && [[ -f "$HOME/dirty_secrets/ours.txt" ]]; then
echo "You have dirty secrets"
fi
File test operators
In the above examples we used only the -f
and -d
operators. But there are a couple other useful operators for dealing with files. They are summed up in the table below.
Operator | Returns true when |
---|---|
-f | file exists and is a regular file |
-d | file exists and is a directory |
-e | file exists |
-s | file is not zero size |
-L | file is a symbolic link |
-S | file is a socket |
-x | file has execute permissions |
Learning more
The best way to learn more is to use Bash. A lot. Don't forget that Google is your friend.
In case you learn well from books I would recommend these.