What command can be used to check if a directory exists or not, within a Bash shell script?
Here's a very pragmatic idiom:
(cd $dir) || return # Is this a directory,
# and do we have access?
I typically wrap it in a function:
can_use_as_dir() {
(cd ${1:?pathname expected}) || return
}
Or:
assert_dir_access() {
(cd ${1:?pathname expected}) || exit
}
The nice thing about this approach is that I do not have to think of a good error message.
cd
will give me a standard one line message to standard error already. It will also give more information than I will be able to provide. By performing the cd
inside a subshell ( ... )
, the command does not affect the current directory of the caller. If the directory exists, this subshell and the function are just a no-op.
Next is the argument that we pass to cd
: ${1:?pathname expected}
. This is a more elaborate form of parameter substitution which is explained in more detail below.
Tl;dr: If the string passed into this function is empty, we again exit from the subshell ( ... )
and return from the function with the given error message.
Quoting from the ksh93
man page:
${parameter:?word}
If
parameter
is set and is non-null then substitute its value; otherwise, printword
and exit from the shell (if not interactive). Ifword
is omitted then a standard message is printed.
and
If the colon
:
is omitted from the above expressions, then the shell only checks whether parameter is set or not.
The phrasing here is peculiar to the shell documentation, as word
may refer to any reasonable string, including whitespace.
In this particular case, I know that the standard error message 1: parameter not set
is not sufficient, so I zoom in on the type of value that we expect here - the pathname
of a directory.
A philosophical note:
The shell is not an object oriented language, so the message says pathname
, not directory
. At this level, I'd rather keep it simple - the arguments to a function are just strings.