To check if a directory exists in a 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, 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 "$LINK_OR_DIR"
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.
Best Solution
The
(
and)
run the command in a subshell. This means that a separate shell is spawned off and the command is run. This is probably because they wanted to use shell specific operation (backgrounding - other examples are redirection etc.). The first&
in the command backgrounds the command run in the subshell (ie.make foo
). The second ampersand backgrounds the subshell itself so that you get back your command prompt immediately.You can see the effects here
Foreground on the current shell
Background on the current shell
Using a subshell (Foreground)
In this case, the current shell waits for the subshell to finish even though the job in the subshell itself is backgrounded.
Using a subshell (BAckground)
The foreground shell returns immediately (Doesn't wait for the subshell which itself doesn't wait for the ls to finish). Observe the difference the command executed.
A sidenote on the need to run some commands in a subshell. Suppose you wanted to run a "shell command" (ie. One that uses shell specific stuff like redirects, job ids etc.), you'd have to either run that command in a subshell (using
(
,)
) or using the-c
option to shells like bash. You can't just directlyexec
such things because the shell is necessary to process the job id or whatever. Ampersanding that will have the subshell return immediately. The second ampersand in your code looks (like the other answer suggests) redundant. A case of "make sure that it's backgrounded".