Estado de salida diferente de cero para salida limpia
15
¿Es aceptable devolver un código de salida distinto de cero si el programa en cuestión se ejecutó correctamente? Por ejemplo, supongamos que tengo un programa simple que (solo) hace lo siguiente:
El programa toma N argumentos. Devuelve un código de salida de min (N, 255). Tenga en cuenta que cualquier N es válido para el programa.
Un programa más realista podría devolver diferentes códigos para programas ejecutados con éxito que significan cosas diferentes. ¿Deberían estos programas escribir esta información en una secuencia, como stdout?
Depende del medio ambiente, pero diría que es de mal estilo.
Los sistemas tipo Unix tienen una convención fuerte de que un estado de salida de 0 denota éxito, y cualquier estado de salida distinto de cero denota falla. Algunos, pero no todos, los programas distinguen entre diferentes tipos de fallas con diferentes códigos de salida distintos de cero; por ejemplo, grepgeneralmente devuelve 0 si se encontró el patrón, 1 si no lo fue y 2 (o más) si hubo un error, como la falta de un archivo.
Esta convención está bastante conectada a los shells de Unix. Por ejemplo, en sh, bashy otros shells tipo Bourne, la ifdeclaración trata un estado de salida 0 como exitoso / verdadero, y un estado de salida distinto de cero como falla / falso:
if your-command
then
echo ok
else
echo FAILURE
fi
Creo que las convenciones bajo MS Windows son similares.
Ahora, ciertamente, nada le impide escribir su propio programa que utiliza códigos de salida no convencionales, especialmente si nada más va a interactuar con él, pero tenga en cuenta que está violando una convención bien establecida, y podría volver y morderlo más tarde .
La forma habitual para que un programa devuelva este tipo de información es imprimirlo en stdout:
En OpenVMS, el éxito se indica con valores impares y el fracaso con valores pares. El valor es un entero de 32 bits con subcampos: bits de control, número de instalación, número de mensaje y gravedad. Los valores de gravedad se dividen entre éxito (Éxito, Informativo) y fracaso (Advertencia, Error, Fatal).
Agregaré que siempre terminamos teniendo alguna depuración debido a esto: la mayoría de las utilidades asumen que el código de salida 0 == es exitoso, así que se asuste cuando robocopy devuelve 1 porque copió cosas no cero porque no copió cosas pero no No se produce un error tampoco.
no devolver 0 para una ejecución exitosa es una mala idea, ya que puede causar confusión a quienes ejecutan su programa. ¿Qué pasaría si algunos ejecutaran su programa más de 100 veces con diferentes entradas y quisieran saber cuántos fallaron o se completaron con éxito? Tener un solo valor de éxito hace que sea mucho más fácil detectar diferencias que tener muchos valores diferentes.
Si tiene un programa que tiene múltiples rutas de retorno exitosas que pueden significar cosas diferentes, diría que es una señal de que su programa está mal diseñado.
Sé de un caso que creo que es aceptable. Sé de un marco de prueba que existe con el número total de fallas de prueba. Entonces, por ejemplo, si el corredor de prueba se completa sin pruebas fallidas, sale con cero. Si una prueba falla, a pesar de que el corredor de prueba corrió correctamente, sale con uno 1. Si dos fallan, devuelve 2, etc. Esto sube a 250, lo que significa "250 o más fallas de prueba".
Utiliza códigos de salida> 250 para indicar salidas anormales.
Si bien esto viola la convención, funciona bien en la práctica.
No creo que esto hace violar convenciones - la prueba tiene éxito si no hay errores; cualquier código de resultado distinto de cero indica pruebas fallidas.
Bevan
1
Eso es "salir con un estado de error para indicar más de 0 errores" y aunque puede violar la semántica común exacta del estado de salida, ciertamente no viola la convención más grande "0 está bien, cualquier cosa mayor que 0 es un error" .
Vatine
2
Realmente depende de lo que intentes transmitir con el código. DB2, por ejemplo, devuelve 100 si no se encuentran datos, otros valores positivos para advertencias y valores negativos para errores. Oracle hace algo similar.
Entonces, si hay diferentes estados de éxito, puede valer la pena usar valores de retorno variables.
Un código de salida de 0 significa que había una actualización disponible y que se descargó e instaló correctamente si no se especificó --checkonly.
Un código de salida de 1 significa que no hay actualizaciones nuevas disponibles.
Un código de salida de 2 significa ...
En este caso, la salida 1 es simplemente un código informativo. Sin embargo, si hubiera escrito el código, no habría elegido 1 ya que eso generalmente falla en la red.
set -e
alguna parte.grep
,diff
devuelve 1 cuando se encuentran diferencias; y> 1 si ocurrió un error.Depende de lo que espere su entorno.
Mi favorito para la extrañeza, de Wikipedia :
fuente
Creo que hay un precedente si el código de salida está devolviendo información significativa y relevante a la persona que llama y la definición de éxito no es realmente binaria. El precedente en el que estoy pensando es la robocopia que devuelve una serie de cosas diferentes dependiendo de lo que sucedió .
Agregaré que siempre terminamos teniendo alguna depuración debido a esto: la mayoría de las utilidades asumen que el código de salida 0 == es exitoso, así que se asuste cuando robocopy devuelve 1 porque copió cosas no cero porque no copió cosas pero no No se produce un error tampoco.
fuente
no devolver 0 para una ejecución exitosa es una mala idea, ya que puede causar confusión a quienes ejecutan su programa. ¿Qué pasaría si algunos ejecutaran su programa más de 100 veces con diferentes entradas y quisieran saber cuántos fallaron o se completaron con éxito? Tener un solo valor de éxito hace que sea mucho más fácil detectar diferencias que tener muchos valores diferentes.
Si tiene un programa que tiene múltiples rutas de retorno exitosas que pueden significar cosas diferentes, diría que es una señal de que su programa está mal diseñado.
fuente
Sé de un caso que creo que es aceptable. Sé de un marco de prueba que existe con el número total de fallas de prueba. Entonces, por ejemplo, si el corredor de prueba se completa sin pruebas fallidas, sale con cero. Si una prueba falla, a pesar de que el corredor de prueba corrió correctamente, sale con uno 1. Si dos fallan, devuelve 2, etc. Esto sube a 250, lo que significa "250 o más fallas de prueba".
Utiliza códigos de salida> 250 para indicar salidas anormales.
Si bien esto viola la convención, funciona bien en la práctica.
fuente
Realmente depende de lo que intentes transmitir con el código. DB2, por ejemplo, devuelve 100 si no se encuentran datos, otros valores positivos para advertencias y valores negativos para errores. Oracle hace algo similar.
Entonces, si hay diferentes estados de éxito, puede valer la pena usar valores de retorno variables.
fuente
Un buen ejemplo: man sa-update (spamassassin)
CÓDIGOS DE SALIDA
En este caso, la salida 1 es simplemente un código informativo. Sin embargo, si hubiera escrito el código, no habría elegido 1 ya que eso generalmente falla en la red.
fuente