How can I check if a directory exists in a Bash shell script?

后端 未结 30 1990
猫巷女王i
猫巷女王i 2020-11-22 10:35

What command can be used to check if a directory exists or not, within a Bash shell script?

相关标签:
30条回答
  • 2020-11-22 11:17
    if [ -d "$DIRECTORY" ]; then
        # Will enter here if $DIRECTORY exists
    fi
    

    This is not completely true...

    If you want to go to that directory, you also need to have the execute rights on the directory. Maybe you need to have write rights as well.

    Therefore:

    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
    
    0 讨论(0)
  • 2020-11-22 11:21

    To check if a directory exists in a shell script, you can use the following:

    if [ -d "$DIRECTORY" ]; then
      # Control will enter here if $DIRECTORY exists.
    fi
    

    Or to check if a directory doesn't exist:

    if [ ! -d "$DIRECTORY" ]; then
      # Control will enter here if $DIRECTORY doesn't exist.
    fi
    

    However, as Jon Ericson points out, subsequent commands may not work as intended if you do not take into account that a symbolic link to a directory will also pass this check. E.g. running this:

    ln -s "$ACTUAL_DIR" "$SYMLINK"
    if [ -d "$SYMLINK" ]; then 
      rmdir "$SYMLINK" 
    fi
    

    Will produce the error message:

    rmdir: failed to remove `symlink': Not a directory
    

    So symbolic links may have to be treated differently, if subsequent commands expect directories:

    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
    

    Take particular note of the double-quotes used to wrap the variables. The reason for this is explained by 8jean in another answer.

    If the variables contain spaces or other unusual characters it will probably cause the script to fail.

    0 讨论(0)
  • 2020-11-22 11:21

    Or for something completely useless:

    [ -d . ] || echo "No"
    
    0 讨论(0)
  • 2020-11-22 11:21

    There are great solutions out there, but ultimately every script will fail if you're not in the right directory. So code like this:

    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
    

    will execute successfully only if at the moment of execution you're in a directory that has a subdirectory that you happen to check for.

    I understand the initial question like this: to verify if a directory exists irrespective of the user's position in the file system. So using the command 'find' might do the trick:

    dir=" "
    echo "Input directory name to search for:"
    read dir
    find $HOME -name $dir -type d
    

    This solution is good because it allows the use of wildcards, a useful feature when searching for files/directories. The only problem is that, if the searched directory doesn't exist, the 'find' command will print nothing to standard output (not an elegant solution for my taste) and will have nonetheless a zero exit. Maybe someone could improve on this.

    0 讨论(0)
  • 2020-11-22 11:23

    Type this code on the Bash prompt:

    if [ -d "$DIRECTORY" ]; then
        # If true this block of code will execute
    fi
    
    0 讨论(0)
  • 2020-11-22 11:24

    Have you considered just doing whatever you want to do in the if rather than looking before you leap?

    I.e., if you want to check for the existence of a directory before you enter it, try just doing this:

    if pushd /path/you/want/to/enter; then
        # Commands you want to run in this directory
        popd
    fi
    

    If the path you give to pushd exists, you'll enter it and it'll exit with 0, which means the then portion of the statement will execute. If it doesn't exist, nothing will happen (other than some output saying the directory doesn't exist, which is probably a helpful side-effect anyways for debugging).

    It seems better than this, which requires repeating yourself:

    if [ -d /path/you/want/to/enter ]; then
        pushd /path/you/want/to/enter
        # Commands you want to run in this directory
        popd
    fi
    

    The same thing works with cd, mv, rm, etc... if you try them on files that don't exist, they'll exit with an error and print a message saying it doesn't exist, and your then block will be skipped. If you try them on files that do exist, the command will execute and exit with a status of 0, allowing your then block to execute.

    0 讨论(0)
提交回复
热议问题