Are you writing a Bash script? Checking if a file or directory exists to perform a conditional task is a very common task one might want to achieve. Let's take a look at how that is done in Bash.
The Bash shell has a few built-in file test operators and by using them you can perform these checks.
Test condition | Description |
---|---|
-f | Check if file exists |
-d | Check if directory exists |
Let's take a look at an example of checking if the user's .bashrc
file exists or not.
#!/usr/bin/env bash
my_file="${HOME}/.bashrc"
if [[ -f "${my_file}" ]]; then
echo "File '${my_file}' exists."
else
echo "File '${my_file}' DOES NOT exist."
fi
If I execute this script on my computer, I get the following output:
File '/home/pratham/.bashrc' exists.
To check for a directory, replace the -f
operator (which is used for checking if a file exists or not) with the -d
operator.
Example 1: A traditional approach
Usually, the Bash built-in test operators are used in combination with the if conditional, like I demonstrated above. This has two advantages. The first advantage is that, by using the -f
and -d
test operators in the if conditional, you can integrate it in your mind more easily since you probably know how to use if
in Bash.
Let's take a look at an example script that checks for the Neovim config file and creates it if it does not exist.
#!/usr/bin/env bash
NVIM_DIR="${HOME}/.configa/nvim"
NVIM_CONF="${NVIM_DIR}/init.lua"
if [[ ! -d "${NVIM_DIR}" ]]; then
echo "Directory '${NVIM_DIR}' does not exist, creating it..."
mkdir -p "${NVIM_DIR}"
fi
if [[ ! -f "${NVIM_CONF}" ]]; then
echo "File '${NVIM_CONF}' does not exist, creating it..."
echo "vim.opt.number = true" > "${NVIM_CONF}"
echo "vim.opt.relativenumber = true" >> "${NVIM_CONF}"
fi
echo -e "\nFile contents:"
cat "${NVIM_CONF}"
In this Bash script, I have declared two variables:
NVIM_DIR
: Absolute path to the Neovim configuration directoryNVIM_CONF
: Absolute path to the inital configuration file that Neovim loads
As you can see, I am performing two checks. The first check is to make sure that the Neovim configuration directory exists or not. I intentionally added the logical NOT operator (!
) to make the condition opposite. This is me saying "I am only concerned if the directory does not exist".
And, if the Neovim configuration directory does not exist, I create it using the mkdir
command.
The second check is a similar check, for the Neovim initial configuration file. Since I am concerned with the check only if the file does not exist, I add the logical NOT operator (!
) here too. If the file does not exist, I populate it with two lines using he echo
built-in.
Finally, I cat
the file's content to the terminal.
Following is the output I get from running this script:
Directory '/home/pratham/.config/nvim' does not exist, creating it...
File '/home/pratham/.config/nvim/init.lua' does not exist, creating it...
File contents:
vim.opt.number = true
vim.opt.relativenumber = true
Example 2: A shortcut ;)
If you know the [
operator (yes, it is an operator!), you will know that there is a shortcut!
Try executing the following script:
#!/usr/bin/env bash
[[ -d "${HOME}" ]] && echo "I have a home directory"
[[ -f "${HOME}/.zshrc" ]] && echo "I am probably using Zsh"
[[ -d "${HOME}/.config/nvim" ]] && echo "Ah, a Neovim user, quite the taste :)"
[[ -f /etc/nixos/configuration.nix ]] || echo "Have you tried NixOS?"
This script is checking the following things:
- If you have a
$HOME
directory - If you have a
~/.zshrc
file - If you have a
~/.config/nvim
directory - If you have a
/etc/nixos/configuration.nix
file
Based on the result and the used logial AND or logical OR operator used with these tests, a statement will be printed to the your terminal.
Following is the output from my computer:
I have a home directory
Ah, a Neovim user, quite the taste :)
Conclusion
The Bash shell has -f
and -d
file test operators that are used to check the existence of a file and a directory respectively. In this article, I demonstrate its use.