Just like we have Linux files, directories are equally important resources. We can say a directory is simply a file that contains other files, since directories are just Linux files. It is a folder meant to store files and folders. We often write our Bash scripts to download files in a particular directory, only if it exists.
Any type of file, be it regular, special, or directory, has to be present in directories since Linux sticks to a hierarchical structure for organizing files and directories. Thus, this makes our job easier to check whether a directory exists. In this article, we will focus on different methods by which we can determine the same.
Using if statement
We can use the -d option, which is readily available with us, to see if a directory exists.
[ -d DIR ]
if [ -d /home/ubuntu ]; then echo true; else echo false; fi if [ -d alpha ]; then echo true; else echo false; fi
The -d flag checks if the specified directory exists. If it does, a zero return status is generated and the if condition of the code is executed. In the second case, a non-zero return status results in the execution of the else part. However, the results may be surprising when symbolic links are involved.
Handling symbolic links
There could be instances where we could have symbolic links to the directory. As we know these links are just shortcuts, we won’t be able to perform the operations which we do for regular directories. Subsequent commands may not always produce the right results if we do not consider the fact that a symbolic link to a directory will also pass this check.
#!/bin/bash DIR=/home/ubuntu/test1Shortcut if [ -d "$DIR" ] then if [ -L "$DIR" ] then echo "Symbolic link." else echo "No symbolic link." fi else echo "Directory doesn't exist." fi
We can prepare a nested if condition by using the -L option. If the input is not a directory, the code will move to the outer else block. However, if it is a directory, we then again check if a symbolic link exists or not by similarly employing the -L option. If a symbolic link exists, the then block of the code will execute which will enable us to treat this link as a regular file.
Using the test Command
We often want to examine the status of directories, whether they exist or are empty. We have a Bash utility named 'test', that helps determine whether a directory exists. Its alias is square brackets ([ ]) We can also take the help of double square brackets ([[ ]]).
test expression [ expression ] [[ expression ]]
#!/bin/bash dirName=/home/ubuntu echo "-----------Using test-----------" if test -d "$dirName" then echo "true" fi echo "-----------Using [ ]-----------" if [ -d "$dirName" ] then echo "true" fi echo "-----------Using [[ ]]-----------" if [[ -d "$dirName" ]] then echo "true" fi echo "-----------Without if-----------" test -d $dirName && echo "true" echo "-----------Using [ ] without if-----------" [ -d "$dirName" ] && echo "true" echo "-----------Using [[ ]] without if-----------" [[ -d "$dirName" ]] && echo "true"
We can couple it with the Bash if statement to develop conditions. It is usually employed for conditional branching and caters to numerical or string comparisons. However, we can determine the status of a file as well. This check is widely used to redirect outputs only if the file exists or to verify if the file was downloaded. We can also use the shorthand technique if we do not wish to use the if statement.
Using ls command
The ls command is a Linux shell utility that lists all the contents of files and directories. We can use this tool to check for the existence of a directory
#!/bin/bash DIR=/home/ubuntu/test1 echo Directory is $DIR if [ "$(ls "$DIR" 2> /dev/null)" ] then echo "Directory exists." else echo "Directory doesn't exist." fi
We can write a simple bash script and use the ls command to check if the directory exists. We just need to surround the expression involving this command in an if statement.
The ls command, if successful, will list the contents and exit with a return status zero. In case of a failure, it will throw an error stating no such file or directory and exit with a non-zero return status. Since we are only interested in the return status and do not want the outcome of ls command, we are redirecting the output as well as any error to the /dev/null file. If the directory exists, ls command will have a zero return status and this will make the then block to execute.
Using find command
We have the Linux find command available with us to check if a directory exists. This utility helps to search the list of files and directories based on conditions specified by us. It walks through the hierarchy of files and directories to locate them.
#!/bin/bash DIR=test1 echo Directory is $DIR if [ "$(find /home/ubuntu -type d -name "$DIR")" ] then echo "Directory exists." else echo "Directory doesn't exist." fi
We use the find command to check for the existence of a directory in our home directory. We can include regular expressions to look for the matching criteria. We have to specify the type option with the character d to ensure only directories are searched. Find provides us with a lot of flexibility when it comes to searching. We have the option to recursively check for the existence of a specific directory in the entire file system. We can use the -maxdepth flag and specify the number of levels we want to go inside to look for the directory.
Check if directory does not exist
We can negate the expression by using the exclamation mark (!). It acts as the logical not operator.
if [ ! -d /etc -a ! -e /etc ]; then echo "Dir does not exist"; else echo "Dir exists"; fi if [ ! -d /home/ubuntu -a ! -e /home/ubuntu ]; then echo "Dir does not exist"; else echo "Dir exists"; fi if [ ! -d alpha -a ! -e /alpha ]; then echo "Dir does not exist"; else echo "Dir exists"; fi if [ ! -d /tmp -a ! -e /tmp ]; then echo "Dir does not exist"; else echo "Dir exists"; fi
This approach works exactly the same way as with the -d option. The only difference is that it checks whether the directory does not exist as there is a presence of the ! operator. It is always safer to have an additional check to make sure that the directory doesn’t exist as a file. Hence we have added an "if exists" check to resolve the conflict between file and directory name.
This check is often used by developers to create a directory only if it doesn’t exist.
DIR=/home/ubuntu/test1 DIR2=/home/ubuntu/test2 if [ ! -d "$DIR" ]; then mkdir $DIR; fi mkdir -p $DIR2
We are checking if the given directory, stored in the variable, exists or not. Since there is the negation (!) operator and as the directory doesn’t exist, it will execute the then block of the code. Hence, mkdir command will execute which will create the directory. Additionally, we can use the -p option readily available with the mkdir command which follows the same flow and creates the directory only if it was non-existent.
Check if multiple directories exist
We can also test if multiple directories exist in a single check.
[ -d /etc -a -d /home/ubuntu ] && echo "Both the directories exist" [[ -d /etc && -d /home/ubuntu ]] && echo "Both the directories exist" if [ -d /etc -a -d /home/ubuntu ] ; then echo "Both the directories exist"; fi if [[ -d /etc && -d /home/ubuntu ]]; then echo "Both the directories exist"; fi
Instead of writing complex nested if conditions, Bash ensures that we can verify if multiple directories exist in a single check using the "and" operator. This operator has to be used differently with the expression we use. If we use the single square brackets to carry out the check, we have to use -a to join two conditions. Similarly, for double square brackets, we must use the && symbol as the and operator.
Other Primary Expressions
With Bash, we can also check for specific types of files. The table below lists the operations we can perform on files.
|[ -d DIR ]||Returns true if DIR exists and is a directory.|
|[ -h DIR ]||Returns true if DIR exists and is a symbolic link.|
|[ -r DIR ]||Returns true if DIR exists and is readable.|
|[ -s DIR ]||Returns true if DIR exists and has a size greater than zero.|
|[ -w DIR ]||Returns true if DIR exists and is writable.|
|[ -x DIR ]||Returns true if DIR exists and is executable.|
|[ -L DIR ]||Returns true if DIR exists and is a symbolic link.|
- Bash has provided us with many approaches to examine the status of a directory.
- We can use the NOT (!) operator to perform the negation to determine if a directory does not exist.
- Instead of nesting the if statements, we can conclude if multiple directories exist in just a single check.
- We also have other Bash commands like the ls and the find to look for directories.