在Bash shell脚本中,哪个命令可以检查目录是否存在?
检查目录是否存在:
if [ -d "$DIRECTORY" ]; then
echo "$DIRECTORY does exist."
fi
检查目录是否不存在:
if [ ! -d "$DIRECTORY" ]; then
echo "$DIRECTORY does not exist."
fi
ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then
rmdir "$SYMLINK"
fi
会产生以下错误信息:
rmdir: failed to remove `symlink': Not a directory
因此,如果后续命令期望目录,则需要以不同的方式处理符号链接:
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
请特别注意用于包装变量的双引号。这样做的原因在8jean的另一个答案中有解释。
如果变量包含空格或其他不寻常的字符,则可能会导致脚本失败。
在Bash脚本中引用变量时,始终将变量用双引号括起来。
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
孩子们这些天在他们的目录名中加入空格和许多其他有趣的字符。(空格!在我那个年代,我们没有任何花哨的空格!)
有一天,其中一个孩子将运行您的脚本,并将$DIRECTORY
设置为"My M0viez"
,然后您的脚本将崩溃。 您不想要那样。 所以请使用双引号。if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi
。或者,对于同时适用于链接和目录的单个命令:rm -r tmpdir
。 - michaeltest
更自然地编写逻辑测试。if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
-L
和其他条件表达式的含义,请参阅{{link1:Bash参考文档:6.4 Bash条件表达式}}。[[ ]]
语法,但实际上与 [ ]
没有任何功能上的不同。如果需要可移植性,请使用 [ ]
并使用必要的解决方法。 - dubiousjim-L
已经被弃用了?在哪个系统中?Bash的help test
,GNU coreutils手册或信息页面都没有提到这一点。 - Soren Bjornstad简短形式:
# if $DIR is a directory, then print yes
[ -d "$DIR" ] && echo "Yes"
如果$dir是一个目录,则回显“yes”
?稍微解释一下会更有帮助 :) - Martijn[ -d "$DIR" ]
进行了检查(紧随其后是 && echo Yes
),因此我认为 set -e
不会影响脚本的行为(即如果测试失败,脚本会继续正常运行)。 - tzotset -e
下,行为完全相同。除非 echo 失败,否则脚本将退出。[ -d "$DIR" ]
单独(没有 && cmd ...
)将导致脚本在 set -e
下退出,如果测试失败(即目录不存在或 $DIR
存在但不是目录)。 - dan一个简单的脚本,用于测试目录或文件是否存在:
if [ -d /home/ram/dir ] # For file "if [ -f /home/rama/file ]"
then
echo "dir present"
else
echo "dir not present"
fi
一个简单的脚本,用于检查目录是否存在:
mkdir tempdir # If you want to check file use touch instead of mkdir
ret=$?
if [ "$ret" == "0" ]
then
echo "dir present"
else
echo "dir not present"
fi
以上脚本将检查目录是否存在。
$?
如果上一条命令成功执行,则返回“0”,否则为非零值。假设 tempdir
已经存在。然后执行 mkdir tempdir
将会出现以下错误:
mkdir: 无法创建目录"tempdir": 文件已存在
要检查目录是否存在,您可以使用类似于以下的简单的if
结构:
if [ -d directory/path to a directory ] ; then
# Things to do
else #if needed #also: elif [new condition]
# Things to do
fi
你也可以用否定形式来表达:
if [ ! -d directory/path to a directory ] ; then
# Things to do when not an existing directory
注意: 谨慎操作。在大括号的开头和结尾两边留空格。
使用相同的语法,您可以使用:
-e: any kind of archive
-f: file
-h: symbolic link
-r: readable file
-w: writable file
-x: executable file
-s: file size greater than zero
你可以使用test -d
(参见man test
)。
-d file
如果文件存在且是目录,则返回真。
例如:
test -d "/etc" && echo Exists || echo Does not exist
注意:`test` 命令和条件表达式 `[
`(参见:man [
)是相同的,因此在 shell 脚本中可移植。
[
- 这是 `test` 内置命令的同义词,但最后一个参数必须是文字]
,以匹配开头的[
。
有关可能的选项或更多帮助,请使用以下命令:
help [
help test
man test
或 man [
或者对于完全无用的东西:
[ -d . ] || echo "No"
这是一个非常实用的成语:
(cd $dir) || return # Is this a directory,
# and do we have access?
我通常会将其包装在一个函数中:
can_use_as_dir() {
(cd ${1:?pathname expected}) || return
}
或者:
assert_dir_access() {
(cd ${1:?pathname expected}) || exit
}
cd
命令会给我一个标准的一行消息standard error,它也会提供比我能提供更多的信息。通过在子shell ( ... )
中执行cd
,该命令不会影响调用者的当前目录。如果该目录存在,则此子shell和函数只是无操作。接下来是我们传递给cd
的参数:${1:?pathname expected}
。这是一种更复杂的参数替换形式,下面将详细解释。简而言之:如果传递到该函数的字符串为空,则我们再次从子shell ( ... )
退出,并返回带有给定错误消息的函数。
引用自ksh93
手册:
${parameter:?word}
parameter
并且它非空,则替换其值;否则,打印word
并退出shell(如果不是交互式)。如果省略word
,则会打印标准消息。:
,则shell仅检查参数是否设置。word
可以引用任何合理的字符串,包括空格。1: parameter not set
是不足够的,所以我关注我们在此处期望的值类型 - 目录的pathname
。pathname
而不是directory
。在这个级别上,我更愿意保持简单 - 函数的参数只是字符串。test -d
,如@Grundlefleck所解释的。 - F. Hauri - Give Up GitHub
[ ! -d "$DIRECTORY" ]
的判断结果为真,不仅当$DIRECTORY
不存在时,也包括$DIRECTORY
存在但不是一个目录的情况。考虑使用类似if [ ! -d "$DIRECTORY" ]; then mkdir "$DIRECTORY"; fi
的语句;如果"$DIRECTORY"
是文件,则此语句将失败。(当然,您应该无论如何都检查mkdir
是否成功;因为有许多原因可能导致它失败。) - Keith Thompson-d
) 和符号链接 (-L
),只需在变量后面加上斜杠即可更方便,例如if [ -d "${THING:+$THING/}" ]
。目录不会介意多余的斜杠,文件返回 false,空值保持为空值,也会返回 false。符号链接会被解析为它所指向的目标。当然,这取决于你的目的。如果你想要前往该目录,那么这样做是可以的。但如果你想删除它,那么这个答案中的代码更好。 - ghoti