Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查bashshell脚本中是否存在目录?_Bash_Shell_Unix_Posix - Fatal编程技术网

如何检查bashshell脚本中是否存在目录?

如何检查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 但是,正如

什么命令可用于检查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

但是,正如所指出的,如果不考虑到指向目录的符号链接也将通过此检查,则后续命令可能无法按预期工作。 例如,运行此:

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
    

注意-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手册中找到更多信息。

简称:

#如果$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