在shell脚本中,可以使用什么命令来检查目录是否存在?
在shell脚本中,可以使用什么命令来检查目录是否存在?
要检查shell脚本中是否存在目录,可以使用以下命令:
if [ -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY exists.
fi
或者检查目录是否不存在:
if [ ! -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY doesn't exist.
fi
但是,作为 Jon Ericson 指出,如果您没有考虑到目录的符号链接也会通过此检查,则后续命令可能无法按预期工作。 例如。运行这个:
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解释 在另一个答案。
如果变量包含空格或其他异常字符,则可能导致脚本失败。
要检查shell脚本中是否存在目录,可以使用以下命令:
if [ -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY exists.
fi
或者检查目录是否不存在:
if [ ! -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY doesn't exist.
fi
但是,作为 Jon Ericson 指出,如果您没有考虑到目录的符号链接也会通过此检查,则后续命令可能无法按预期工作。 例如。运行这个:
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脚本。这些天孩子们长大了,他们的目录名称中可以有空格和许多其他有趣的字符。 (太空!回到我的日子,我们没有任何奇特的空间!;))
有一天,其中一个孩子将运行你的脚本 $DIRECTORY
设置 "My M0viez"
而且你的剧本会爆炸。你不希望这样。所以使用它。
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
请注意 -d 测试可以产生一些令人惊讶的结果:
$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory
文件在:“什么时候目录不是目录?”答案是:“当它是目录的符号链接时。”一个稍微彻底的测试:
if [ -d t ]; then
if [ -L t ]; then
rm t
else
rmdir t
fi
fi
我找到了 双托架 的版本 test
使编写逻辑测试更自然:
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
缩短形式:
[ -d "$DIR" ] && echo "Yes"
要检查目录是否存在,您可以使用简单的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
if [ -d "$DIRECTORY" ]; then
# Here if $DIRECTORY exists
fi
您可以使用 test -d
(看到 man test
)。
-d file
如果文件存在且为目录,则为True。
例如:
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
将给我一个标准的一行消息给stderr已经。它还将提供比我能提供的更多信息。通过执行 cd
在子壳内 ( ... )
,该命令不会影响调用者的当前目录。如果目录存在,则此子shell和函数只是一个无操作。
接下来是我们传递给的论点 cd
: ${1:?pathname expected}
。这是参数替换的更精细形式,下面将更详细地解释。
Tl; dr:如果传入此函数的字符串为空,我们再次退出子shell ( ... )
并使用给定的错误消息从函数返回。
引自 ksh93
手册页:
${parameter:?word}
如果
parameter
设置并且为非null,然后替换其值; 否则,打印word
并退出shell(如果不是交互式)。 如果word
省略,然后打印标准消息。
和
如果结肠
:
从上面的表达式中省略,然后是 shell仅检查参数是否已设置。
这里的措辞是shell文档所特有的,如 word
可以参考
到任何合理的字符串,包括空格。
在这种特殊情况下,我知道标准错误消息 1: parameter not set
是不够的,所以我放大了我们期望的价值类型 - pathname
一个目录。
一个哲学说明:
shell不是面向对象的语言,所以消息说 pathname
不是 directory
。在这个层面上,我宁愿保持简单 - 函数的参数只是字符串。