unix verificar archivo - Compruebe si existe un directorio en un script de shell





15 Answers

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
comprobar fichero existencia

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




Me parece que la versión de tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS de la test hace que las pruebas de lógica de escritura sean más naturales:

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



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 



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 [



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.




  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




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
    



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.




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



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



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



file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;



(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 mencionados anteriormente.

Con el comando ls ; los casos en que el directorio no existe - se muestra un mensaje de error

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




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

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





Related