2012-01-16 13 views
10

Soy muy nuevo en scripts bash, y para mi primer intento de script estoy enviando archivos a Dropbox de mi profesor dentro del mismo servidor.Error de script de Bash Captura

El código es el siguiente:

#! /bin/bash 
echo "Submit Lab$1? \c" 

read choice 

if [ $choice = "y" ]; then 
    echo "Sending to Prof's dropbox..." 
    cp -r /path/to/lab$1 /path/to/dropbox 
else 
    echo "Submission terminated." 
fi 

el uso del mandato es simplemente "$ submit 1" (1 es un solo número entero, que corresponde a qué laboratorio Deseo someter)

La escritura del golpe añade la argumento ingresado (un solo entero) para el nombre de archivo necesario (un directorio), luego envía ese directorio al dropbox de mi prof utilizando cp.

Más por el mero hecho de aprender que de la necesidad absoluta, quería crear un mensaje de consulta limpio que detectará cualquier error cp (como el archivo no existente), y podría generar mi propio mensaje de error.

Así que, básicamente, algo así como:

echo "Submit lab$1?" 

read choice 

echo "Send to Prof's dropbox" 
cp -rv /path/to/lab$1 /path/to/dropbox 

<catch any errors from cp> 

if [ cp has errors ] 

    echo "Submission failed." 

else if [ cp has no errors ] 

    echo "Submission successful." 

And so on... 

entiendo que podría utilizar el modo detallado, y que en sí cp imprime errores, pero como se ha dicho antes, yo estoy haciendo esto con el fin de aprender de errores atrapando en bash y siendo capaz de hacer un aviso limpio.

Cualquier ayuda sería apreciada.

Gracias!


también: Tengo un script similar que presenta laboratorios de mi ordenador portátil, utilizando scp. Asumiendo que tengo esta pregunta, ¿puedo aplicar las soluciones a scp exactamente de la misma manera?

EDITAR: No deseo cp errores de salida al shell! El error más común probablemente sería "no se puede descifrar: no hay tal archivo o directorio". Me gustaría detectar ese error y simplemente decir "Falló la presentación".

EDIT # 2: La respuesta de jcollado es correcta, el problema es de mi parte. No terminó el if-else anidado con el "fi" adecuado.

Después de arreglarlo, funcionó según lo previsto. Todavía necesito detectar el resultado del error, pero creo que sé a dónde tengo que ir para resolverlo por mi cuenta, por lo que esta pregunta se responde en lo que a mí respecta.

EDICIÓN FINAL: Ah, qué diablos - el redireccionamiento fue tan fácil que pensé que pondría la solución aquí. Si el uso de Linux, sólo tiene que añadir "2>/dev/null" (si no desea que los mensajes de error que se guardan en cualquier archivo) después de la cp hacer "cp -r /first/path /second/path 2>/dev/null"

Respuesta

23

Aunque se puede probar $ ?, también puede probar el estado de salida de un comando directamente:

if cp -rv /path/to/lab$1 /path/to/dropbox 
then echo Submission successful 
fi 
exit $? 

Los errores ya se informó a la norma error por cp. El exit mostrado saldrá con el estado 0 (correcto) si cp fue exitoso; de lo contrario, sale con el estado con el que salió cp.

Claramente, puede envolver eso en un bucle si lo desea, o puede hacerlo no interactivo (pero cualquier salida finaliza el script).

+0

Gracias por la solución alternativa. La mejor respuesta basada en la simplicidad. – skippr

+0

Creo que el código de salida en lo anterior siempre será cero. Si 'cp' falla (devuelve no-0),' if' devolverá 0. 'echo' de bash siempre devuelve 0. De la página man, con respecto a' if': * El estado de salida es el estado de salida del último comando ejecutado , o cero si ninguna condición es verdadera. * –

+1

@ mr.spuratic: parece que estás en lo correcto. Ejecutando 'si es verdadero; luego echo verdadero; fi; echo $? 'en Bash, Korn shell, Heirloom shell se imprime verdadero y luego 0; reemplázalo con 'si es falso; luego echo verdadero; fi; echo $? 'y solo imprime 0. Por lo tanto, el estado' $? 'no conserva el estado de salida del comando ejecutado en' if'. Hay formas de eso, de mayor o menor elegancia. Uno de ellos es 'status = 0; si es verdad; luego echo verdadero; else estado = 1; fi; echo $ status'. O puede hacer lo inverso: 'status = 1; si es verdad; luego echo verdadero; estado = 0; fi; echo $ status'. –

8

Para comprobar el código de retorno del comando anterior, puede utilizar la $? variable especial de la siguiente manera:

if [ "$?" -ne "0" ]; then 
    echo "Submission failed" 
    exit 1 
fi 

echo "Submission successful." 

Además, si desea una pronta limpia, puede redired stderr como se explica here.

Finalmente, también puede usar esto en la secuencia de comandos que usa scp, ya que funciona independientemente del comando que esté utilizando.

+0

Gracias por la pronta respuesta (sin juego de palabras)! Buscaré más en las redirecciones de stderr, ya que parece ser donde radica la solución de "solicitud limpia". Sin embargo, el código que proporcionó no funciona para envíos fallidos. No imprime "Envío fallido". cuando cp falla. Sin embargo, ignora la "Presentación exitosa" cuando cp falla. – skippr

+0

Observé que cuando cp falla, nada después de que se ejecuta. – skippr

+0

Ah, el problema fue de mi parte. Ya lo pillo. ¡Gracias! – skippr

2
echo "Submit lab$1?" 

read choice 

echo "Send to Prof's dropbox" 
cp -rv /path/to/lab$1 /path/to/dropbox &>/dev/null 

[ $? -eq 0 ] && { #success, do something } || { #fail, do something } 

Y así sucesivamente ...