shell中文 - 检查shell脚本中是否存在目录




unix shell中文 (20)

在shell脚本中,可以使用什么命令来检查目录是否存在?


使用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
    

  1. 一个简单的脚本来测试是否存在目录或文件:

    if [ -d /home/ram/dir ]   # for file "if [-f /home/rama/file]" 
    then 
        echo "dir present"
    else
        echo "dir not present"
    fi
    
  2. 一个简单的脚本,用于检查目录是否存在:

    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':文件存在


ls命令与-l (长列表)选项一起返回有关文件和目录的属性信息。
特别是ls -l输出的第一个字符通常是d或a - (破折号)。 如果是d ,列出的是确定的目录。

只有一行中的以下命令将告诉您给定的ISDIR变量是否包含目录的路径:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

实际用法:

    [[email protected] ~]$ ISDIR="$HOME/Music" 
    [[email protected] ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [[email protected] ~]$ [[ $(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.

    [[email protected] ~]$ touch "empty file.txt"
    [[email protected] ~]$ ISDIR="$HOME/empty file.txt" 
    [[email protected] ~]$ [[ $(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

下面可以找到,

find . -type d -name dirname -prune -print

你有没有考虑过做你想做的任何事情而不是在你跳跃之前寻找?

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

同样的事情适用于cdmvrm等...如果你在不存在的文件上尝试它们,它们将退出并出现错误并打印一条消息,说它不存在,然后你的块将是跳过。 如果您对存在的文件进行尝试,该命令将执行并以状态0退出,允许您执行then块。


使用-e检查将检查文件,这包括目录。

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi

如果要检查目录是否存在,无论它是真实目录还是符号链接,请使用以下命令:

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”后直接检查返回码。


实际上,您应该使用几种工具来获得防弹方法:

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),所以效益大于麻烦。


或者对于完全没用的东西:

[ -d . ] || echo "No"

根据评论:

如果你想创建目录但它还不存在,那么最简单的方法是使用mkdir -p创建目录 - 以及路径上任何缺少的目录 - 如果目录已经存在则不会失败,所以你可以用以下方法一次完成所有操作:

mkdir -p /some/directory/you/want/to/exist || exit 1

注意-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条件表达式[ builtin命令以及[[复合 命令]的更多信息)。


缩短形式:

[ -d "$DIR" ] && echo "Yes"

要检查多个目录,请使用以下代码:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi

要检查目录是否存在,您可以使用简单的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 

这个答案包含在一个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

is_dir

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";

这是一个非常实用的习语:

(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标准的一行消息。 它还将提供比我能提供的更多信息。 通过在子shell ( ... )执行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

philosphical note:shell不是面向对象的语言,因此消息显示pathname ,而不是directory 。 在这个层面上,我宁愿保持简单 - 函数的参数只是字符串。


[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"

[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

注意:引用变量是一种很好的做法。


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

if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi




posix