如何检查bashshell脚本中是否存在目录?
什么命令可用于检查Bash shell脚本中是否存在目录?要检查shell脚本中是否存在目录,可以使用以下命令:如何检查bashshell脚本中是否存在目录?,bash,shell,unix,posix,Bash,Shell,Unix,Posix,什么命令可用于检查Bash 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 但是,正如
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
但是,正如所指出的,如果不考虑到指向目录的符号链接也将通过此检查,则后续命令可能无法按预期工作。 例如,运行此:
ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then
rmdir "$SYMLINK"
fi
将生成错误消息:
rmdir:删除'symlink'失败:不是目录
因此,如果后续命令需要目录,则符号链接可能必须以不同的方式处理:
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
found=`find -type d -name "myDirectory"`
if [ -n "$found" ]
then
# The variable 'found' contains the full path where "myDirectory" is.
# It may contain several lines if there are several folders named "myDirectory".
fi
请特别注意用于包装变量的双引号。其原因由8jean解释 如果变量包含空格或其他异常字符,则可能会导致脚本失败。使用
find
- 检查子目录中是否存在文件夹:
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
found=`find -type d -name "myDirectory"` if [ -n "$found" ] then # The variable 'found' contains the full path where "myDirectory" is. # It may contain several lines if there are several folders named "myDirectory". fi
- 根据当前目录中的模式检查是否存在一个或多个文件夹:
found=`find -maxdepth 1 -type d -name "my*"` if [ -n "$found" ] then # The variable 'found' contains the full path where folders "my*" have been found. fi
found=`find -maxdepth 1 -type d -name "myDirectory"` if [ -n "$found" ] then # The variable 'found' is not empty => "myDirectory"` exists. fi
- 两种组合。在以下示例中,它检查当前目录中是否存在该文件夹:
found=`find -maxdepth 1 -type d -name "my*"` if [ -n "$found" ] then # The variable 'found' contains the full path where folders "my*" have been found. fi
found=`find -maxdepth 1 -type d -name "myDirectory"` if [ -n "$found" ] then # The variable 'found' is not empty => "myDirectory"` exists. fi
$ 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
您可以在和上的Bash手册中找到更多信息。简称:
#如果$DIR是一个目录,则打印yes
[-d“$DIR”]&回显“是”
我发现测试的版本使编写逻辑测试更加自然:
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
在Bash脚本中引用变量时,请记住始终将变量用双引号括起来。如今,孩子们在成长的过程中都有这样的想法:他们的目录名中可以有空格和许多其他有趣的字符。(空间!在我的时代,我们没有特别的空间!;)
有一天,其中一个孩子将运行您的脚本,并将$DIRECTORY
设置为“My M0viez”
,您的脚本将崩溃。你不会想要的。所以用这个
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
或者为了一些完全无用的东西:
[ -d . ] || echo "No"
实际上,您应该使用几种工具来获得防弹方法:
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),因此好处大于麻烦
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists
fi
这不完全是真的
如果要转到该目录,还需要对该目录具有执行权限。也许你也需要有写作权
因此:
if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
# ... to go to that directory (even if DIRECTORY is a link)
cd $DIRECTORY
pwd
fi
上述代码检查目录是否存在以及目录是否可写。与-l
(长列表)选项结合使用的ls
命令返回有关文件和目录的属性信息。
特别是ls-l
输出的第一个字符,它通常是d
或-
(破折号)。在d
的情况下,列出的目录肯定是一个目录
仅一行中的以下命令将告诉您给定的ISDIR变量是否包含目录路径:
[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directory"
实际用途:
[claudio@nowhere ~]$ ISDIR="$HOME/Music"
[claudio@nowhere ~]$ ls -ld "$ISDIR"
drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
[claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directory"
YES, /home/claudio/Music is a directory.
[claudio@nowhere ~]$ touch "empty file.txt"
[claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt"
[claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directoy"
Sorry, /home/claudio/empty file.txt is 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
if [ -d directory/path to a directory ] ; then
# Things to do
else #if needed #also: elif [new condition]
# Things to do
fi
只有在执行时,您所在的目录中有您碰巧要检查的子目录,才会成功执行
我理解这样的初始问题:验证目录是否存在,而不考虑用户在文件系统中的位置。因此,使用“find”命令可以实现以下目的:
dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d
这个解决方案很好,因为它允许使用通配符,这是搜索文件/目录时的一个有用功能。唯一的问题是,如果搜索的目录不存在,“find”命令将不打印任何内容(对于我来说,这不是一个优雅的解决方案),并且仍然会有一个零出口。也许有人可以改进这一点。这里有一个非常实用的成语:
(cd $dir) || return # Is this a directory,
# and do we have access?
我通常将其包装在函数中:
can_use_as_dir() {
(cd ${1:?pathname expected}) || return
}
或:
这种方法的好处是,我不必想一个好的错误消息
cd
将向我发送一条标准的单行消息。它还将提供比我所能提供的更多的信息。通过在子shell中执行cd
(…)
,该命令不会影响调用者的当前目录。如果目录存在,那么这个子shell和函数只是一个no-op
接下来是我们传递给cd
:${1:?预期路径名}
的参数。这是一种更复杂的参数替换形式,下面将对其进行更详细的解释
Tl;dr:如果传递到此函数的字符串为空,我们将再次退出子shell(…)
,并从函数返回给定的错误消息
从
ksh93
手册页中引用:
${parameter:?word}
如果设置了参数
且该参数不为空,则替换其值;
否则,打印word
并退出shell(如果不是交互式的)。
如果省略了word
,则会打印标准消息
及
如果上述表达式中省略了冒号:
,则
shell仅检查是否设置了参数
这里的措辞是shell文档特有的,因为word
可能指任何合理的字符串,包括空格
在这种特殊情况下,我知道标准错误消息1:parameter not set
是不够的,所以我放大了t
if [ -e ${FILE_PATH_AND_NAME} ]
then
echo "The file or directory exists."
fi
find . -type d -name dirname -prune -print
if [ -d "$DIRECTORY" ]; then
# If true this block of code will execute
fi
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
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"
mkdir -p /some/directory/you/want/to/exist || exit 1
test -d "/etc" && echo Exists || echo Does not exist
if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
# Things to do
fi
[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
$ is_dir ~
YES
$ is_dir /tmp
YES
$ is_dir ~/bin
YES
$ mkdir '/tmp/test me'
$ is_dir '/tmp/test me'
YES
$ is_dir /asdf/asdf
NO
# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
echo "Folder doesnt exist: $DIR";
exit;
fi
function show_help()
{
IT=$(CAT <<EOF
usage: DIR
output: YES or NO, depending on whether or not the directory exists.
)
echo "$IT"
exit
}
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$1" ]
then
show_help
fi
DIR=$1
if [ -d $DIR ]; then
echo "YES";
exit;
fi
echo "NO";
[ -d "$directory" ] && echo "exist" || echo "not exist"
test -d "$directory" && echo "exist" || echo "not exist"
if pushd /path/you/want/to/enter; then
# Commands you want to run in this directory
popd
fi
if [ -d /path/you/want/to/enter ]; then
pushd /path/you/want/to/enter
# Commands you want to run in this directory
popd
fi
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