Hice el siguiente script:
# !/bin/bash
# OUTPUT-COLORING
red='\e[0;31m'
green='\e[0;32m'
NC='\e[0m' # No Color
# FUNCTIONS
# directoryExists - Does the directory exist?
function directoryExists {
cd $1
if [ $? = 0 ]
then
echo -e "${green}$1${NC}"
else
echo -e "${red}$1${NC}"
fi
}
# EXE
directoryExists "~/foobar"
directoryExists "/www/html/drupal"
El script funciona, pero además de mis ecos, también está la salida cuando
cd $1
falla en la ejecución.
testscripts//test_labo3: line 11: cd: ~/foobar: No such file or directory
¿Es posible atrapar esto?
bash
shell
shell-script
error-handling
Thomas De Wilde
fuente
fuente
test -d /path/to/directory
(o[[ -d /path/to/directory ]]
en bash) le dirá si un objetivo dado es un directorio o no, y lo hará en silencio.cd
ingresar en él.directoryExists
.Respuestas:
Su script cambia los directorios a medida que se ejecuta, lo que significa que no funcionará con una serie de nombres de ruta relativos. Luego comentaste más tarde que solo querías verificar la existencia del directorio, no la capacidad de uso
cd
, por lo que las respuestas no necesitan usarsecd
en absoluto. Revisado. Usotput
y colores deman terminfo
:(Editado para usar lo más invulnerable en
printf
lugar de la problemáticaecho
que podría actuar sobre las secuencias de escape en el texto).fuente
Se usa
set -e
para establecer el modo de salida en caso de error: si un comando simple devuelve un estado distinto de cero (lo que indica una falla), el shell se cierra.Tenga en cuenta que
set -e
no siempre se activa. Los comandos en las posiciones de prueba pueden fallar (por ejemploif failing_command
,failing_command || fallback
). Los comandos en el subshell solo conducen a salir del subshell, no el padre:set -e; (false); echo foo
muestrafoo
.Alternativamente, o además, en bash (y ksh y zsh, pero no sh simple), puede especificar un comando que se ejecuta en caso de que un comando devuelva un estado distinto de cero, con la
ERR
trampa, por ejemplotrap 'err=$?; echo >&2 "Exiting on error $err"; exit $err' ERR
. Tenga en cuenta que en casos como(false); …
, la trampa ERR se ejecuta en la subshell, por lo que no puede hacer que el padre salga.fuente
||
comportamiento, que permite realizar fácilmente el manejo adecuado de errores sin usar trampas. Mira mi respuesta . ¿Qué opinas sobre ese método?ERR
seudoseñal es compatible con todos los shells principales. Gracias por el comentario! =)Para ampliar la respuesta de @Gilles :
De hecho,
set -e
no funciona dentro de los comandos si usa el||
operador después de ellos, incluso si los ejecuta en una subshell; por ejemplo, esto no funcionaría:Pero el
||
operador es necesario para evitar el regreso de la función externa antes de la limpieza.Hay un pequeño truco que se puede utilizar para solucionar esto: ejecute el comando interno en segundo plano y luego espere inmediatamente. El
wait
builtin devolverá el código de salida del comando interno, y ahora está usando||
despuéswait
, no la función interna, por lo queset -e
funciona correctamente dentro de este último:Aquí está la función genérica que se basa en esta idea. Debería funcionar en todos los shells compatibles con POSIX si elimina las
local
palabras clave, es decir, reemplace todolocal x=y
con solox=y
:Ejemplo de uso:
Ejecutando el ejemplo:
Lo único que debe tener en cuenta al usar este método es que todas las modificaciones de las variables de Shell realizadas desde el comando al que pasa
run
no se propagarán a la función de llamada, porque el comando se ejecuta en una subshell.fuente
No dice exactamente qué quiere decir con
catch
--- informe y continúe; abortar procesamiento adicional?Como
cd
devuelve un estado distinto de cero en caso de error, puede hacer lo siguiente:Simplemente puede salir en caso de falla:
O haga eco de su propio mensaje y salga:
Y / o suprimir el error proporcionado por
cd
en caso de falla:Según los estándares, los comandos deben colocar mensajes de error en STDERR (descriptor de archivo 2). Por lo tanto,
2>/dev/null
dice redirigir STDERR al "bit-bucket" conocido por/dev/null
.(no olvide citar sus variables y marcar el final de las opciones para
cd
).fuente
En realidad para su caso, diría que la lógica se puede mejorar.
En lugar de cd y luego verifique si existe, verifique si existe y luego vaya al directorio.
Pero si su propósito es silenciar los posibles errores
cd -- "$1" 2>/dev/null
, entonces , esto hará que depurar en el futuro sea más difícil. Puede verificar los indicadores if testing en: Bash if documentación :fuente
$1
variable y fallará si esa variable contiene espacios en blanco u otros metacaracteres de shell. Tampoco verifica si el usuario tiene permiso paracd
ingresar.