Pregunta

¿Qué comando se puede utilizar para comprobar si un directorio existe o no, dentro de un script de shell?

¿Fue útil?

Solución

Para verificar si existe un directorio en un script de shell, puede usar lo siguiente:

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

O para comprobar si un directorio no existe:

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

Sin embargo, como Jon Ericson señala, es posible que los comandos posteriores no funcionen según lo previsto si no se tiene en cuenta que un enlace simbólico a un directorio también pasará esta verificación.P.ej.ejecutando esto:

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

Producirá el mensaje de error:

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

Por lo tanto, es posible que los enlaces simbólicos deban tratarse de manera diferente, si los comandos posteriores esperan directorios:

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

Tome nota particular de las comillas dobles utilizadas para envolver las variables, el motivo de esto lo explica 8jean en otra respuesta.

Si las variables contienen espacios u otros caracteres inusuales, probablemente provocará que el script falle.

Otros consejos

Recuerde siempre envolver variables en citas dobles al hacerlas referirlas en un script bash.Los niños de hoy en día crecen con la idea de que pueden tener espacios y muchos otros personajes divertidos en los nombres de sus directorios.(¡Espacios!¡En mis días, no teníamos espacios lujosos!;))

Un día, uno de esos niños ejecutará tu script con $DIRECTORY ajustado a "My M0viez" y tu guión explotará.No quieres eso.Entonces usa esto.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi

Nota la -d La prueba puede producir algunos resultados sorprendentes:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

Archivo bajo:"¿Cuándo un directorio no es un directorio?" La respuesta:"Cuando es un enlace simbólico a un directorio". Una prueba un poco más completa:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

Puede encontrar más información en el manual de Bash en expresiones condicionales de bash y el [ comando incorporado y el [[ comando compuesto.

encuentro el doble soporte versión de test hace que escribir pruebas de lógica sea más natural:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi

Forma más corta:

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

Para comprobar si existe un directorio, puede utilizar una estructura if simple como esta:

if [ -d directory/path to a directory ] ; then
#Things to do

else #if needed #also: elif [new condition] 
# things to do
fi

Puedes hacerlo también en negativo.

if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory

Nota:Tenga cuidado, deje espacios vacíos a ambos lados de los tirantes de apertura y cierre.

Con la misma sintaxis puedes usar:

-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 "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi

Puedes usar test -d (ver man test).

-d file Verdadero si el archivo existe y es un directorio.

Por ejemplo:

test -d "/etc" && echo Exists || echo Does not exist

Nota:El test El comando es lo mismo que la expresión condicional. [ (ver: man [), por lo que es portátil entre scripts de shell.

[ - Este es un sinónimo de test incorporado, pero el último argumento debe ser literal ], para que coincida con la apertura [.

Para posibles opciones o más ayuda, consulte:

  • help [
  • help test
  • man test o man [
  1. Un script simple para probar si el directorio o el archivo está presente o no:

    if [ -d /home/ram/dir ]   # for file "if [-f /home/rama/file]" 
    then 
        echo "dir present"
    else
        echo "dir not present"
    fi
    
  2. Un script simple para verificar si el directorio está presente o no:

    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
    

    Los scripts anteriores comprobarán que el directorio esté presente o no.

    $? si el último comando es exitoso, devuelve "0"; de lo contrario, un valor distinto de cero.suponer tempdir ya esta presente entonces mkdir tempdir dará un error como el siguiente:

    mkdir:No se puede crear el directorio 'tempdir':El archivo existe

O por algo completamente inútil:

[ -d . ] || echo "No"

He aquí un modismo muy pragmático:

(cd $dir) || return # is this a directory,
                    # and do we have access?

Normalmente lo envuelvo en una función:

can_use_as_dir() { 
    (cd ${1:?pathname expected}) || return
}

O:

assert_dir_access() { 
    (cd ${1:?pathname expected}) || exit
}

Lo bueno de este enfoque es que no tengo que pensar en un buen mensaje de error.

cd Ya me dará un mensaje estándar de una línea a stderr.También proporcionará más información de la que yo podré proporcionar.Al realizar la cd dentro de una subcapa ( ... ), el comando no afecta el directorio actual de la persona que llama.Si el directorio existe, esta subcapa y la función simplemente no funcionan.

El siguiente es el argumento que pasamos a cd: ${1:?pathname expected}.Esta es una forma más elaborada de sustitución de parámetros que se explica con más detalle a continuación.

Dr.:Si la cadena pasada a esta función está vacía, salimos nuevamente del subshell ( ... ) y regresar de la función con el mensaje de error dado.


Citando del ksh93 página de manual:

${parameter:?word}

Si parameter está establecido y no es nulo, entonces sustituya su valor;de lo contrario, imprima word y salir del shell (si no es interactivo).Si word se omite, se imprime un mensaje estándar.

y

Si los dos puntos : se omite de las expresiones anteriores, entonces el shell solo verifica si el parámetro está configurado o no.

La redacción aquí es peculiar de la documentación del shell, ya que word Puede referirse a cualquier cadena razonable, incluido el espacio en blanco.

En este caso particular, sé que el mensaje de error estándar 1: parameter not set no es suficiente, así que me acerco al tipo de valor que esperamos aquí: el pathname de un directorio.

Una nota filosófica:El shell no es un lenguaje orientado a objetos, por lo que el mensaje dice pathname, no directory.En este nivel, prefiero mantenerlo simple: los argumentos de una función son solo cadenas.

if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

El código anterior comprueba si el directorio existe y si se puede escribir.

Escriba este código en el mensaje de bash

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi

Más funciones usando find

  • Verifique la existencia de la carpeta dentro de los subdirectorios:

    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
    
  • Verifique la existencia de una o varias carpetas según un patrón dentro del directorio actual:

    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
    
  • Ambas combinaciones.En el siguiente ejemplo, comprueba la existencia de la carpeta en el directorio actual:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
    

En realidad, deberías utilizar varias herramientas para conseguir un enfoque a prueba de balas:

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

No hay necesidad de preocuparse por espacios y caracteres especiales siempre que utilice "${}".

Tenga en cuenta que [[]] no es tan portátil como [], pero dado que la mayoría de la gente trabaja con versiones modernas de Bash (ya que después de todo, la mayoría de la gente ni siquiera trabaja con la línea de comando :-p), el beneficio es mayor que el problema.

Para verificar más de un directorio use este código:

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

¿Has considerado simplemente hacer lo que quieras hacer en el if en lugar de mirar antes de saltar?

Es decir, si desea verificar la existencia de un directorio antes de ingresarlo, intente hacer esto:

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

Si el camino que le das pushd existe, lo ingresarás y saldrá con 0, lo que significa el then parte de la declaración se ejecutará.Si no existe, no sucederá nada (aparte de algún resultado que indique que el directorio no existe, lo que probablemente sea un efecto secundario útil de todos modos para la depuración).

Parece mejor que esto, que requiere repetirlo:

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

Lo mismo funciona con cd, mv, rm, etc...si los prueba en archivos que no existen, saldrán con un error e imprimirán un mensaje diciendo que no existe, y su then Se omitirá el bloque.Si los prueba en archivos que existen, el comando se ejecutará y saldrá con un estado de 0, permitiendo a su then bloque a ejecutar.

Compruebe si el directorio existe; de ​​lo contrario, cree uno.

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

NÓTESE BIEN:Citar variables es una buena práctica.

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

esta respuesta envuelto como un script de shell

Ejemplos

$ 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

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

Utilizando el -e check buscará archivos y esto incluye directorios.

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

según jonathan comentario:

Si desea crear el directorio y aún no existe, entonces la técnica más sencilla es utilizar mkdir -p que crea el directorio (y cualquier directorio que falte en la ruta) y no falla si el directorio ya existe, por lo que puedes hacerlo todo a la vez con:

mkdir -p /some/directory/you/want/to/exist || exit 1
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Eso no es completamente cierto...Si desea ir a ese directorio, también necesita tener derechos de ejecución en el directorio.Quizás también necesites tener derechos de escritura.

Por lo tanto:

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

El ls comando en conjunto con -l La opción (lista larga) devuelve información de atributos sobre archivos y directorios.
En particular, el primer personaje de ls -l salida suele ser una d o un - (estrellarse).En caso de un d el que aparece en la lista es un directorio con seguridad.

El siguiente comando en solo una línea le dirá si el dado ISDIR La variable contiene una ruta a un directorio o no:

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

Uso práctico:

    [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
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;

Si desea verificar si existe un directorio, independientemente de si es un directorio real o un enlace simbólico, use esto:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

Explicación:El comando "ls" da un error "ls:/X:No existe tal archivo o directorio" si el directorio o enlace simbólico no existe, y también establece el código de retorno, que puede recuperar mediante "$?", en no nulo (normalmente "1").Asegúrese de verificar el código de retorno directamente después de llamar a "ls".

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

Si encuentra un problema con uno de los enfoques proporcionados anteriormente.

Con ls dominio;Los casos en los que el directorio no existe: se muestra un mensaje de error.

$ [[ ls -ld SAMPLE_DIR| grep ^d | wc -l -eq 1]] && echo existe || no existe -ksh:no:no encontrado [No existe tal archivo o directorio]

Existen excelentes soluciones, pero en última instancia, todos los scripts fallarán si no estás en el directorio correcto.Entonces codifique como este:

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

se ejecutará exitosamente sólo si en el momento de la ejecución estás en un directorio que tiene un subdirectorio que buscas.

Entiendo la pregunta inicial así:para verificar si un directorio existe independientemente de la posición del usuario en el sistema de archivos.Entonces, usar el comando 'buscar' podría ser la solución:

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

Esta solución es buena porque permite el uso de comodines, una característica útil al buscar archivos/directorios.El único problema es que, si el directorio buscado no existe, el comando 'buscar' no imprimirá nada en la salida estándar (no es una solución elegante para mi gusto) y, no obstante, tendrá una salida cero.Quizás alguien podría mejorar esto.

A continuación se puede utilizar la búsqueda,

find . -type d -name dirname -prune -print
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top