What command can be used to check if a directory does or does not exist, within a bash shell script?
To check if a directory exists in a bash shell script you can use the following:
if [ -d "$DIRECTORY" ]; then # Control will enter here if $DIRECTORY exists fi
Or to check if a directory doesn't exist:
if [ ! -d "$DIRECTORY" ]; then # Control will enter here if $DIRECTORY doesn't exist fi
However, as Jon Ericson points out (thanks Jon), subsequent commands may not work as intended if you do not take into account that a symbolic link to a directory will also pass this check. E.g. running this:
ln -s "$ACTUAL_DIR" "$SYMLINK" if [ -d "$SYMLINK" ]; then rmdir "$SYMLINK" fi
Will produce the error message:
rmdir: failed to remove `symlink': Not a directory
So symbolic links may have to be treated differently, if subsequent commands expect directories:
if [ -d "$LINK_OR_DIR" ]; then if [ -L "$LINK_OR_DIR" ]; then # It is a symlink! # Symbolic link specific commands go here rm "$LINK_OR_DIR" else # It's a directory! # Directory command goes here rmdir "$SYMLINK" fi fi
Take particular note of the double-quotes used to wrap the variables, the reason for this is explained by 8jean in another answer.
If the variables contain spaces or other unusual characters it will probably cause the script to fail.
You could use the find command
found=`find -type d -name "myDirectory"`
if [ -n "$found"]
then
# found is not empty
fi
Note the -d test can produce some surprising results:
$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory
File under: "When is a directory not a directory?" The answer: "When it's a symlink to a directory." A slightly more thorough test:
if [ -d t ]; then
if [ -L t ]; then
rm t
else
rmdir t
fi
fi
(I'd have made this a comment, since it's not really the right answer, just an elaboration on the right answer, but the comment box is far too constraining. Feel free to add this material to the answer itself.)
I find the double-bracket version of test
makes writing logic tests more natural:
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
And I see that the double-bracket operator is often faster.
Grundlefleck wrote:
if [ -d $DIRECTORY ]; then
Remember to always wrap variables in double quotes when interpolating them in a bash script. Kids these days grow up with the idea that they can have spaces and lots of other funny characters in their directory names. (Spaces! Back in my days, we didn't have no fancy spaces!) ... ;)
One day, one of those kids will run your script with $DIRECTORY
set to "My M0viez"
and you script will blow up. You don't want that. So use
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
instead.
Actually, you should use several tools to get a bullet proof approach:
DIR_PATH=`readlink -f "${the_stuff_you_test}"` # get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; then # now you're testing
echo "It's a dir";
fi
No need to worry about spaces and special characters as long as you use "${}"
Note that [[]]
is not as portable as []
but since most people work with modern versions of bash (since after all, most people don't even work with command line :-p), the benefit is greater than the trouble.
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists
fi
This is not completely true... If you want to go to that directory, you also needs to have the execute rights on the directory. Maybe you need to have write rights as well.
Therfore:
if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
# ... to go to that directory (even if DIRECTORY is a link)
cd $DIRECTORY
pwd
fi
if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
# ... to go to that directory and write something there (even if DIRECTORY is a link)
cd $DIRECTORY
touch foobar
fi
No need to check to see if DIR or SYMLINK to issue separate RM or RMDIR commands. Just use rm -rf (-r recusively remove and -f means force, no prompts)
I'd also check that you aren't attempting to remove "/" (root) or current directory.
if [ -d "$DIR" ] && [ "$DIR" != "/" ] && [ "$DIR" != "." ] && [ "$DIR" != "./" ]; then rm -rf $DIR fi
if [ -d "$Directory" -a -w "$Directory" ]
then
#Statements
fi
Above code check if directory exists and and if it is writable.
-MuraliKrishna.B