verificar Compruebe si existe un directorio en un script de shell




verificar si existe un archivo en unix (24)

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

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

¿Qué comando se puede usar para verificar si un directorio existe o no dentro de un script de shell?


El comando ls junto con la opción -l (lista larga) devuelve información de atributos sobre archivos y directorios.
En particular, el primer carácter de la salida de ls -l suele ser un d o un - (guión). En el caso de una d la lista es un directorio seguro.

El siguiente comando en una sola línea le dirá si la variable ISDIR dada 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:

    [[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

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

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 señala Jon Ericson , es posible que los comandos subsiguientes no funcionen según lo previsto si no tiene en cuenta que un enlace simbólico a un directorio también pasará esta verificación. 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, los enlaces simbólicos deben ser tratados de manera diferente, si los comandos subsiguientes 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 en particular de las comillas dobles utilizadas para envolver las variables, la razón de esto se explica por 8jean en otra respuesta .

Si las variables contienen espacios u otros caracteres inusuales, es probable que la secuencia de comandos falle.


Para verificar si existe un directorio, puede usar simple si la estructura es la siguiente:

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 las llaves de apertura y de 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 

En realidad, debes usar varias herramientas para obtener 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 tiene que preocuparse por los espacios y los caracteres especiales siempre que use "${}" .

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


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

Compruebe si el directorio existe, de lo contrario haga uno

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY

Escriba este código en el prom bash

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

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

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

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

NB: Cotizar variables es una buena práctica.


Según el comentario de :

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

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

Excelentes soluciones, pero al final todos los scripts fallarán si no estás en el directorio correcto. Así el código 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á correctamente solo si en el momento de la ejecución se encuentra en un directorio que tiene un subdirectorio que debe verificar.

Entiendo la pregunta inicial como esta: para verificar si un directorio existe independientemente de la posición del usuario en el sistema de archivos. Así que usar el comando 'encontrar' podría hacer el truco:

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 cuando se buscan 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, sin embargo, tendrá una salida cero. Tal vez alguien podría mejorar en esto.


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 comando de test es el mismo que la expresión condicional [ (ver: man [ )], por lo que es portátil en los scripts de shell.

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

Para posibles opciones o ayuda adicional, verifique:

  • help [
  • help test
  • man test o de man [

Recuerde siempre envolver las variables entre comillas dobles cuando haga referencia a ellas en un script de bash. Los niños en estos días 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á su script con $DIRECTORY configurado en "My M0viez" y su script explotará. Tú no quieres eso. Así que usa esto.

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

Más características usando find

  • Compruebe 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 basadas en 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, verifica 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
    

Tenga en cuenta que la prueba -d 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 sobre expresiones condicionales de Bash y en el comando [[ builtin y el comando compuesto [[ .


Aquí hay un lenguaje 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 dará más información de la que podré proporcionar. Al ejecutar el cd dentro de una subshell ( ... ) , el comando no afecta el directorio actual de la persona que llama. Si el directorio existe, esta subshell y la función son simplemente no operativas.

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

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

Citando la página del manual de ksh93 :

${parameter:?word}

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

y

Si se omiten los dos puntos de las expresiones anteriores, el shell solo comprueba si el parámetro está establecido o no.

El fraseo aquí es peculiar a la documentación del shell, ya que word puede referirse a cualquier cadena razonable, incluyendo espacios en blanco.

En este caso particular, sé que el mensaje de error estándar 1: parameter not set es suficiente, por lo que me acerco al tipo de valor que esperamos aquí: la pathname de 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 que sea simple: los argumentos de una función son solo cadenas.


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

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

El uso de la -e comprueba si hay archivos y esto incluye directorios.

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

  1. Un script simple para probar si el directorio o 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 si el directorio está presente o no.

    $? si el último comando tiene éxito, devuelve "0"; Supongamos que tempdir ya está presente, entonces mkdir tempdir dará un error como el siguiente:

    mkdir: no se puede crear el directorio 'tempdir': el archivo existe


Esta respuesta envuelta 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

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


if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Esto no es completamente cierto ... Si desea ir a ese directorio, también necesita tener los derechos de ejecución en el directorio. Tal vez usted necesita tener derechos de escritura también.

Por lo que

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




posix