Bash Script to check if file exists
Sometimes we need to check whether a file exists or not in Linux machines when running our bash scripts. There are many efficient and elegant ways to check if a file exist using BASH in our automation workflow.
The most basic way or single command to check if a file exists is the test
command.
test -f filename
If the file exits, the above command will exit with status code 0 and if it doesn't than the status code will be 1.
A simple example use case would be:
test -f filename && echo "File exits" || echo "File not found"
We will be discussing the following methods to check if a file or directory exist or not:
- the test command to check if a file exists
- short version of test command
- advanced if…else one-liners
- test command to check if directory exists
- the test command to check multiple files
- test command flags to check specific type of existing file
Let dive deep into this and other methods to check whether a file exits.
1. Check if file exist using test
command in Linux
The test
command has the following syntax:
test EXPRESSION
The test command is generally used for evaluating any expression and then execute something based on the results.
But how I know the status code with that command exited?
Just run the echo $?
command to know the status code of command previous command executed.
Let's take a quick example:
test 50 -gt 49 && echo "Bingo! True" || echo "Nah! False"
In the above example, we are using the test
command to check if 50 is greater than 49, and based on that the echo
command is executed. So the output for this command will be,
Bingo! True
Here is the complete guide to help you learn more about if…else statements in bash.
Checking if a File exists in Linux using test
command
To check if a file exists, the most common option used with the test
command are -e
, and -f
.
- The
-e
checks if a file exists (node, block, file, directory) considering everything is file in Linux.
- But
-f
is for when you want to ensure the file is a regular file (not a directory, or device).
For example, to check if test is a file in the /etc/ directory, any of the following commands would work.
#!/bin/bash
FILE="/etc/test"
if test -f "$FILE"; then
echo "Exist"
else
echo "NOT"
fi
The above code can also be executed as below. The test
command can also be used as double square brackets [[ ]]
, enclosing the expression, like we have done below.
The above examples can be broken down as follows:
-
The test
command is run on a given expression. The expression is to check if the file exists or not.
-
The result is passed to an if
block. If true, the command within the if
block is executed, otherwise a else-if
, or else
block if any, are executed.
It is recommended to quote variables, especially when they contain spaces or special characters to avoid unwanted escaping by the shell, on expansion.
2. Shorthand version of test
command
It is not necessary to use the test
keyword if you want to run the test
command. We can also enclose the expression directly into square brackets [ ]
or double square brackets [[ ]]
. For example:
[ 50 -gt 49 ] && echo "Bingo! True" || echo "Nah! False"
# or use double brackets
[[ 50 -gt 49 ]] && echo "Bingo! True" || echo "Nah! False"
As stated in above Bash comment, We can use one or two brackets.
We will see more of this form also in examples below.
Most modern shells, such as BASH, FISH, ZSH, KSH, support the test
expression.
Check if file exist with expressions in BASH
The above commands can also be written without an if
with the help of &&
, and ||
operators. Let's see:
#!/bin/bash
FILE="/etc/test"
[ -f "$FILE" ] && echo "Exist" || echo "NOT"
Let's run it in the shell and see,
The command runs in the same manner as before, that is, if true, whatever is after the &&
is executed. If false, everything after ||
is run, or we continue to the next statement, if any.
3. Advanced Bash scripting with if-else one-liner (multiple commands)
To execute multiple commands, there are two ways to do it.
The curly braces { }
lets us execute multiple statements. For example:
#!/bin/bash
FILE="/etc/test"
[ -f "$FILE" ] && { echo "Exist"; pwd; } || echo "NOT"
Let's run it in the shell and see,
We can see that the file /etc/test does not exist, as the output is NOT
.
While the parentheses ()
spawns a subshell. Any changes to the environment (or in the shell), done inside the parenthesis ()
, will not be reflected after the ()
. For example:
#!/bin/bash
FILE="/etc/test"
[ -f "$FILE" ] && echo "Exist" || { echo "NOT"; ( cd ~/Documents; pwd; ) && pwd; }
In the bash script above:
- we are checking for a file, and
- in the else case (if the file is not found), we
echo
NOT,
- and then spawn a subshell inside which we move out into the Documents directory,
- execute
pwd
command,
- and then when the execution exits the subshell.
We are still in the parent directory and not in the Documents directory, because that was inside the subshell that we moved to the Documents directory and that has no effect outside.
4. Checking if a Directory exists in Linux
Sometimes we need to check for a directory, and though we can use -e
, it is an ambiguous check for any type of Linux file. To ensure we check only for a directory, we use the -d
flag with test
command, in place of -f
(regular Linux file).
For example, to check whether the Documents directory exists in our home (~
shortcut will not work) directory, the following is to be executed:
#!/bin/bash
DIR="/home/user/Documents"
if [ -d "$DIR" ]; then
echo "Exist"
fi
Let's run it in the shell and see,
As you can see, the script output says the directory exists. Let's see how we can check if a directory does not exist.
Check if the Directory does not exist in Linux
Like all programming languages, Bash supports negation, with the help of the !
keyword.
For example, we want to create a directory Pictures, in case it does not exist, instead of writing the check within an else
block, we could just negate our test to see if the file exists, in the following manner:
#!/bin/bash
DIR="/home/user/scripts"
if [ ! -d "$DIR" ]; then
mkdir "$DIR"
echo "$DIR has been created"
fi
Let's run it in the shell and see,
As you can see in the screenshot above, the non-existing directory has been created.
5. Checking for multiple Files in Linux
To check when multiple files exist simultaneously, or if one of the multiple files exist, we can use the following formats of the test
command.
Using double square braces offers the option of using the &&
bash operator, in the following manner:
#!/bin/bash
FILE1="/home/user/.bashrc"
FILE2="/home/user/.profile"
if [[ -f "$FILE1" && -f "$FILE2" ]]; then
echo "Both files exist"
fi
Let's run it in the shell and see,
Check if file and directory exist in bash
If you want to check whether a file by the name test exists in /etc/, or a directory by the name of Documents exists in ~
, we run the following:
#!/bin/bash
FILE="/home/user/.bashrc"
DIR="/etc/"
if [ -f "$FILE" -a -d "$DIR" ]; then
echo "Both exist"
fi
Here, you use -a
to make sure that both expressions are correct. It is like &&
operator.
We can see that both the file and the directory exists.
6. Linux test
command Flags/Options
Above only three flags have been covered, but for there are many out there, so you can try different flags in case of some specific needs:
Option |
Description |
-G FILE |
FILE exists and is owned by the effective group ID of the current user |
-N FILE |
FILE exists and has been modified since the last read |
-O FILE |
FILE exists and is owned by the effective user ID of the current user |
-r FILE |
FILE exists and read permission is granted |
-s FILE |
FILE exists and size is greater than zero |
-S FILE |
FILE exists and is a socket |
-w FILE |
FILE exists and write permission is granted |
-x FILE |
FILE exists and execute permission is granted |
Just as for -d
, -e
, or -f
, to negate, or search for the opposite, we add a !
.
To know more about the test
command, the Linux manual-pages (man
) can be referred to using man test
or man [
.
On major systems, “[“ is offered as an executable, and to check if your system has any such executable, run:
which [
/usr/bin/[
If a path is printed on the terminal, we can also run the following, which prints the help section of the man page to the terminal.
/usr/bin/[ --help # Or use the path printed by the previous command
This tutorial has covered how to use the test
command in various scenarios, with the most basic flags for the existence of a file, or a directory or both. We have also covered some more additional flags that are available, and how they can be used. Feel free to play more with test command and do not forget to use Bash for loop to optimize your code and repeat any block of code.