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.cdingresar 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 usarsecden absoluto. Revisado. Usotputy colores deman terminfo:(Editado para usar lo más invulnerable en
printflugar de la problemáticaechoque podría actuar sobre las secuencias de escape en el texto).fuente
Se usa
set -epara 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 -eno 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 foomuestrafoo.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
ERRtrampa, 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?ERRseudoseñal es compatible con todos los shells principales. Gracias por el comentario! =)Para ampliar la respuesta de @Gilles :
De hecho,
set -eno 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
waitbuiltin devolverá el código de salida del comando interno, y ahora está usando||despuéswait, no la función interna, por lo queset -efunciona 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
localpalabras clave, es decir, reemplace todolocal x=ycon 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
runno 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
cddevuelve 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
cden 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/nulldice 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
$1variable y fallará si esa variable contiene espacios en blanco u otros metacaracteres de shell. Tampoco verifica si el usuario tiene permiso paracdingresar.