什么命令检查Bash shell脚本中是否存在目录?
当前回答
较短形式:
# if $DIR is a directory, then print yes
[ -d "$DIR" ] && echo "Yes"
其他回答
在Bash脚本中引用变量时,始终将变量括在双引号中。
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
现在的孩子们在他们的目录名中添加空格和许多其他有趣的字符。(空间!在我的时代,我们没有花哨的空间!)有一天,这些孩子中的一个会运行你的脚本,$DIRECTORY设置为“My M0viez”,你的脚本就会崩溃。你不想这样。所以使用双引号。
我发现双括号版本的测试使编写逻辑测试更自然:
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
这里有一个非常实用的成语:
(cd $dir) || return # Is this a directory,
# and do we have access?
我通常将其包装在函数中:
can_use_as_dir() {
(cd ${1:?pathname expected}) || return
}
Or:
assert_dir_access() {
(cd ${1:?pathname expected}) || exit
}
这种方法的好处是,我不必想到好的错误消息。
cd会给我一条标准的单行消息,告诉我标准错误。它还将提供我无法提供的更多信息。通过在子shell(…)中执行cd,该命令不会影响调用者的当前目录。如果目录存在,则此子shell和函数只是一个no-op。
接下来是传递给cd:${1:?路径名应为}的参数。这是一种更为复杂的参数替换形式,将在下面进行更详细的解释。
T1;dr:如果传入此函数的字符串为空,我们将再次从子shell(…)退出,并返回带有给定错误消息的函数。
引用ksh93手册页:
${parameter:?word}
若参数设置为非空,则替换其值;否则,打印word并退出shell(如果不是交互式的)。若单词被省略,则打印标准消息。
and
如果在上述表达式中省略冒号:,则shell只检查是否设置了参数。
这里的措辞是shell文档特有的,因为单词可以指任何合理的字符串,包括空格。
在这种特殊情况下,我知道标准错误消息1:parameter not set是不够的,所以我放大了我们期望的值类型——目录的路径名。
哲学笔记:
shell不是面向对象的语言,因此消息中显示的是路径名,而不是目录。在这个层次上,我宁愿保持简单——函数的参数只是字符串。
if [ -d "$Directory" -a -w "$Directory" ]
then
#Statements
fi
上述代码检查目录是否存在以及是否可写。
实际上,您应该使用几种工具来获得防弹方法:
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
只要使用“${}”,就不必担心空格和特殊字符。
请注意,[[]]不像[]那样可移植,但由于大多数人都使用现代版本的Bash(毕竟,大多数人甚至不使用命令行:-p),所以好处大于麻烦。