Signup/Sign In

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:

  1. the test command to check if a file exists
  2. short version of test command
  3. advanced if…else one-liners
  4. test command to check if directory exists
  5. the test command to check multiple files
  6. 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.

test for file existence

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.

test expression if else one liner

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,

test without if

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.

  • Bash supports braces ({}),

  • and parentheses (())

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,

test multiple commands

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:

  1. we are checking for a file, and
  2. in the else case (if the file is not found), we echo NOT,
  3. and then spawn a subshell inside which we move out into the Documents directory,
  4. execute pwd command,
  5. and then when the execution exits the subshell.

test multiple commands

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,

test directory

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,

test for not existing file

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,

test multiple files

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.

Check if file and directory exist in BASH

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

/usr/bin/[ or test command in Linux

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.



About the author:
Pradeep has expertise in Linux, Go, Nginx, Apache, CyberSecurity, AppSec and various other technical areas. He has contributed to numerous publications and websites, providing his readers with insightful and informative content.