¿Qué comando se puede usar para verificar si un directorio existe o no, dentro de un script de shell Bash?
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 verificar 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 , los comandos posteriores pueden no funcionar según lo previsto si no tiene en cuenta que un enlace simbólico a un directorio también pasará esta verificación. Ej. Ejecutar 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 pueden tener que 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 ajustar las variables. La razón de esto se explica por 8jean en otra respuesta .
Si las variables contienen espacios u otros caracteres inusuales, probablemente hará que el script falle.
--
se recomienda su uso (marcador de fin de opciones). De lo contrario, si su variable contiene algo que parece una opción, el script fallará al igual que con los espacios.[ ! -d "$DIRECTORY" ]
será verdad o bien si$DIRECTORY
no existe, o si lo hace existe, pero no es un directorio. Considera algo comoif [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi
; esto fallará si"$DIRECTORY"
es un archivo. (Por supuesto, usted debe comprobar simkdir
tuvieron éxito todos modos, hay una serie de razones por las que puede fallar.)-d
) como el enlace simbólico (-L
), es más fácil agregar una barra diagonal a la variable, comoif [ -d "${THING:+$THING/}" ]
. A un directorio no le importará la barra extra. Un archivo se evaluará como falso. Vacío permanecerá vacío, tan falso. Y un enlace simbólico se resolverá en su destino. Por supuesto, depende de tu objetivo. Si quieres ir allí, está bien. Si desea eliminarlo , entonces el código en esta respuesta es mejor.Recuerde siempre envolver las variables entre comillas dobles cuando haga referencia a ellas en un script Bash. En la actualidad, los niños 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 elegantes!;))
Un día, uno de esos niños ejecutará su script con
$DIRECTORY
set to"My M0viez"
y su script explotará. No quieres eso. Entonces usa esto.fuente
Tenga en cuenta que la prueba -d puede producir algunos resultados sorprendentes:
Archivo bajo: "¿Cuándo un directorio no es un directorio?" La respuesta: "Cuando se trata de un enlace simbólico a un directorio". Una prueba un poco más exhaustiva:
Puede encontrar más información en el manual de Bash sobre las expresiones condicionales de Bash y el
[
comando incorporado y el comando[[
compuesto .fuente
if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi
... o, para un comando que funciona en ambos enlaces y directorios:rm -r tmpdir
Creo que la versión de doble paréntesis
test
hace que escribir pruebas de lógica sea más natural:fuente
if [[ -d "$TARFILE" ]]
[[ ]]
se admite la ceniza con opciones de compilación predeterminadas , pero de hecho no proporciona ninguna funcionalidad diferente[ ]
. Si la portabilidad es una preocupación, quédese[ ]
y use las soluciones necesarias.Forma más corta:
fuente
if $dir is a dir, then echo "yes"
? Un poco de explicación ayudaría :)cmd && other
es una abreviatura común paraif cmd; then other; fi
: funciona con la mayoría de los lenguajes de programación que admiten la lógica booleana, y se conoce como evaluación de cortocircuito .set -e
(que es una práctica recomendada de programación de shell ).[ -d "$DIR" ]
está marcado (seguido de&& echo Yes
), por lo que creoset -e
que no hace ninguna diferencia en el comportamiento del script (es decir, si la prueba falla, el script continúa normalmente).Para verificar si existe un directorio, puede usar una
if
estructura simple como esta:También puedes hacerlo en negativo:
Nota : ten cuidado. Deje espacios vacíos a ambos lados de las llaves de apertura y cierre.
Con la misma sintaxis puedes usar:
fuente
Un script simple para probar si un directorio o archivo está presente o no:
Un script simple para verificar si el directorio está presente o no:
Las secuencias de comandos anteriores verificarán si el directorio está presente o no
$?
si el último comando es exitoso, devuelve "0", de lo contrario, un valor distinto de cero. Supongamostempdir
que ya está presente. Luegomkdir tempdir
dará un error como el siguiente:fuente
Puedes usar
test -d
(verman test
).Por ejemplo:
Nota: El
test
comando es el mismo que la expresión condicional[
(ver:)man [
, por lo que es portátil a través de scripts de shell.Para posibles opciones o ayuda adicional, verifique:
help [
help test
man test
oman [
fuente
O para algo completamente inútil:
fuente
Aquí hay un lenguaje muy pragmático:
Normalmente lo envuelvo en una función:
O:
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 al error estándar . También proporcionará más información de la que podré proporcionar. Al realizarcd
dentro de una subshell( ... )
, el comando no afecta el directorio actual de la persona que llama. Si el directorio existe, este subshell y la función son solo un no-op.El siguiente es el argumento de 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.Tl; dr: si la cadena que se pasa 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 de la
ksh93
página del manual:y
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 amplío el tipo de valor que esperamos aquí: elpathname
de un directorio.Una nota filosófica:
El shell no es un lenguaje orientado a objetos, por lo que el mensaje dice que
pathname
nodirectory
. En este nivel, prefiero que sea simple: los argumentos de una función son solo cadenas.fuente
test -d
como explicó @Grundlefleck.test -d /unreadable/exists
fallará, incluso si el argumento existe.El código anterior verifica si el directorio existe y si se puede escribir.
fuente
Probar en línea
fuente
space
después[
-> [`` -d . recibí un error por falta de espacioEscriba este código en el indicador de Bash:
fuente
Más funciones con
find
Verifique la existencia de la carpeta dentro de los subdirectorios:
Verifique la existencia de una o varias carpetas en función de un patrón dentro del directorio actual:
Ambas combinaciones. En el siguiente ejemplo, verifica la existencia de la carpeta en el directorio actual:
fuente
find -maxdepth 1 -type d -name 'pattern'
. ¿Te importa si añado en tu respuesta este truco? Cheers;)En realidad, debe usar varias herramientas para obtener un enfoque a prueba de balas:
No hay necesidad de preocuparse por espacios y caracteres especiales siempre y cuando utilice
"${}"
.Tenga en cuenta que
[[]]
no es tan portátil como[]
, pero dado que la mayoría de las personas trabajan 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 comando :-p), el beneficio es mayor que el problema.fuente
¿Has considerado simplemente hacer lo que quieras hacer en el
if
lugar de mirar antes de saltar?Es decir, si desea verificar la existencia de un directorio antes de ingresarlo, intente hacer esto:
Si el camino que le das
pushd
existe, lo ingresarás y saldrá con0
, lo que significa quethen
se ejecutará parte de la declaración. 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 para la depuración).Parece mejor que esto, que requiere repetirse:
Lo mismo funciona con
cd
,mv
,rm
, etc ... si se los pruebe archivos que no existen, que van a salir con un error e imprimir un mensaje que dice que no existe, y suthen
se omitirán bloque. Si los prueba en archivos que existen, el comando se ejecutará y saldrá con un estado de0
, permitiendo que suthen
bloque se ejecute.fuente
Explicación:
-d
: verifica si es un directorio-L
: verifica si es un enlace simbólicofuente
Para verificar más de un directorio, use este código:
fuente
Verifique si el directorio existe, de lo contrario haga uno:
fuente
mkdir -p "$DIRECTORY"
para el mismo efecto.fuente
Esta respuesta envuelta como un script de shell
Ejemplos
is_dir
fuente
El uso de la
-e
comprobación buscará archivos y esto incluye directorios.fuente
Según el comentario de Jonathan :
Si desea crear el directorio y todavía no existe, entonces la técnica más simple es usar el
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 a la vez con:fuente
Eso no es completamente cierto...
Si desea ir a ese directorio, también debe tener los derechos de ejecución en el directorio. Quizás también necesite tener derechos de escritura.
Por lo tanto:
fuente
Usa el
file
programa. Teniendo en cuenta que todos los directorios también son archivos en Linux, bastaría con emitir el siguiente comando:file $directory_name
Comprobación de un archivo inexistente:
file blah
Salida:
cannot open 'blah' (No such file or directory)
Comprobando un directorio existente:
file bluh
Salida:
bluh: directory
fuente
El
ls
comando junto con la-l
opción (lista larga) devuelve información de atributos sobre archivos y directorios.En particular, el primer carácter de
ls -l
salida suele ser ad
o a-
(guión). En el caso ded
uno, el listado es un directorio seguro.El siguiente comando en una sola línea le dirá si la
ISDIR
variable dada contiene una ruta a un directorio o no:Uso práctico:
fuente
fuente
Si desea verificar si existe un directorio, independientemente de si es un directorio real o un enlace simbólico, use esto:
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 "$?", A no -nulo (normalmente "1"). Asegúrese de verificar el código de retorno directamente después de llamar "ls".
fuente
if ! ls $DIR 2>/dev/null; then echo "$DIR does not exist!"; fi
(1)
(2)
(3)
Si se encuentra un problema con uno de los enfoques proporcionados anteriormente:
Con el
ls
comando; los casos en que no existe un directorio: se muestra un mensaje de errorfuente
Existen excelentes soluciones, pero en última instancia, cada script fallará si no está en el directorio correcto. Entonces código como este:
se ejecutará con éxito solo si en el momento de la ejecución se encuentra en un directorio que tiene un subdirectorio en el que está buscando.
Entiendo la pregunta inicial como esta: para verificar si existe un directorio independientemente de la posición del usuario en el sistema de archivos. Entonces, usar el comando 'encontrar' podría hacer el truco:
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 tendrá una salida cero. Tal vez alguien podría mejorar esto.
fuente
locate
pero no para nada más ...