在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解释.
如果变量包含空格或其他异常字符,则可能导致脚本失败.
请记住,在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
您可以在Bash手册中找到有关Bash条件表达式和[
内置命令以及[[
复合命令的更多信息.
我发现双括号版本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 /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 [ -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中执行内部( ... )
命令,该命令不会影响调用者的当前目录.如果目录存在,则此子shell和函数只是一个无操作.
接下来是我们传递给的论点cd
:${1:?pathname expected}
.这是更精细的参数替换形式,下面将更详细地解释.
Tl; dr:如果传入此函数的字符串为空,我们再次退出子shell ( ... )
并从函数返回给定的错误消息.
引用ksh93
手册页:
${parameter:?word}
如果
parameter
设置并且为非null,则替换其值; 否则,打印word
并退出shell(如果不是交互式的).如果word
省略,则打印标准消息.
和
如果
:
从上面的表达式中省略了冒号,那么shell只检查参数是否设置.
这里的措辞是shell文档所特有的,word
可以引用任何合理的字符串,包括空格.
在这种特殊情况下,我知道标准错误消息1: parameter not set
是不够的,所以我放大了我们期望的值类型 - pathname
目录.
一个philosphical note:shell不是面向对象的语言,所以消息说pathname
不是directory
.在这个级别,我宁愿保持简单 - 函数的参数只是字符串.
if [ -d "$Directory" -a -w "$Directory" ] then #Statements fi
上面的代码检查目录是否存在以及它是否可写.
在bash promt上键入此代码
if [ -d "$DIRECTORY" ]; then # if true this block of code will execute fi
find
检查子目录中是否存在文件夹:
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
实际上,您应该使用几种工具来获得防弹方法:
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
而不是在你跳跃之前看?
IE,如果要在输入之前检查目录是否存在,请尝试执行以下操作:
if pushd /path/you/want/to/enter; then # commands you want to run in this directory popd fi
如果你给出的路径pushd
存在,你将输入它并且它将退出0
,这意味着then
语句的一部分将被执行.如果它不存在,则不会发生任何事情(除了某些输出说该目录不存在,这可能是一个有用的副作用,无论如何调试).
似乎比这更好,这需要重复自己:
if [ -d /path/you/want/to/enter ]; then pushd /path/you/want/to/enter # commands you want to run in this directory popd fi
同样的事情与工作cd
,mv
,rm
,等...如果你试戴不存在的文件,他们将用一个错误退出,并打印一条消息说它不存在,你的then
块将被跳过.如果您对存在的文件进行尝试,该命令将执行并以状态退出0
,允许您的then
块执行.
要检查多个目录,请使用以下代码:
if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then # Things to do fi
检查目录是否存在,否则创建一个
[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"
注意:引用变量是一种很好的做法.
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
这个答案包含在一个shell脚本中
$ 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 <
22> bailey86..:使用
-e
检查将检查文件,这包括目录.if [ -e ${FILE_PATH_AND_NAME} ] then echo "The file or directory exists." fi
23> kenorb..:根据乔纳森的评论:
如果你想创建目录并且它还不存在,那么最简单的方法是使用
mkdir -p
它创建目录 - 以及路径上任何缺少的目录 - 如果目录已经存在则不会失败,所以你可以全部完成同时:mkdir -p /some/directory/you/want/to/exist || exit 1
24> Vishal..:DIRECTORY=/tmp if [ -d "$DIRECTORY" ]; then echo "Exists" fi
在线尝试
25> 小智..:if [ -d "$DIRECTORY" ]; then # Will enter here if $DIRECTORY exists fi这不完全正确......如果要转到该目录,还需要拥有该目录的执行权限.也许你还需要拥有写权.
Therfore:
if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then # ... to go to that directory (even if DIRECTORY is a link) cd $DIRECTORY pwd fi
if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then # ... to go to that directory and write something there (even if DIRECTORY is a link) cd $DIRECTORY touch foobar fi
26> ztank1013..:该
ls
命令与-l
(long listing)选项一起返回有关文件和目录的属性信息.
特别是ls -l
输出的第一个字符通常是ad
或a-
(破折号).如果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
27> Sudip Bhanda..:
file
程序怎么样。考虑到所有目录也是linux中的文件,发出以下命令就足够了:
file $directory_name
检查不存在的文件:
file blah
输出:
cannot open 'blah' (No such file or directory)
检查现有目录:
file bluh
输出:
bluh: directory
28> ajmartin..:file="foo" if [[ -e "$file" ]]; then echo "File Exists"; fi;
29> derFunk..:如果要检查目录是否存在,无论它是真实目录还是符号链接,请使用以下命令:
ls $DIR if [ $? != 0 ]; then echo "Directory $DIR already exists!" exit 1; fi echo "Directory $DIR does not exist..."说明:如果目录或符号链接不存在,"ls"命令会给出错误"ls:/ x:没有这样的文件或目录",并且还可以通过"$?"将返回代码设置为非-null(通常为"1").确保在调用"ls"后直接检查返回码.
或者你可以使用这个较短的版本:`if!ls $ DIR 2>/dev/null; 然后回声"$ DIR不存在!"; fi`
30> Piyush Baija..:(1)
[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"(2)
[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"(3)
[[ -d run_dir && ! -L run_dir ]] && echo Exists || echo "Not Exists"如果发现上述方法之一存在问题.
用
ls
命令; 目录不存在的情况 - 显示错误消息$ [[
ls -ld SAMPLE_DIR| grep ^d | wc -l
-eq 1]] && echo存在|| 不存在-ksh:not:not found [没有这样的文件或目录]