¿Cuándo utilizar el flujo de error estándar en la aplicación de línea de comandos?

9

¿Hay alguna directriz para usar el error al escribir una aplicación de línea de comandos? Para mi sorpresa, no encontré nada cuando busqué en Google.

En particular, la pregunta que me preocupa en este momento es si usarla stdouto stderrcuando el usuario llamó al programa con argumentos ilegales. Sin embargo, una respuesta más completa es muy apreciada porque seguramente este no será el único caso en el que se necesita una regla clara para escribir un programa que se comporte de la manera que espera el usuario.

UTF-8
fuente
¿Está bien que esos mensajes de error se mezclen con la salida normal? Por ejemplo, ¿es el programa un filtro para datos?
thrig
No es un filtro de datos. Tampoco es interactivo. El usuario lo llama con argumentos (entre los cuales se encuentran rutas de archivos), el programa funciona, cambia esos archivos, imprime algunos mensajes, idealmente no imprime ningún mensaje de error y finaliza.
UTF-8

Respuestas:

15

Sí, muestra un mensaje sobre stderrcuándo se utilizan los argumentos incorrectos. Y si eso también hace que la aplicación salga, salga con un estado de salida distinto de cero.

Debe usar el flujo de error estándar para los mensajes de diagnóstico o para la interacción del usuario. Los mensajes de diagnóstico incluyen mensajes de error, advertencias y otros mensajes que no forman parte de la salida de la utilidad cuando funciona correctamente ("correctamente", lo que significa que no ocurre nada excepcional, como archivos que no se encuentran o lo que sea).

Muchos shells (¿todos?) Muestran avisos, lo que el usuario escribe y los menús, etc. stderrpara que la redirección stdoutno le impida interactuar con el shell de una manera significativa.

Lo siguiente es de una publicación de blog sobre este tema:

Esta es una cita de Doug McIllroy, inventor de las tuberías Unix, que explica cómo stderrsurgió. 'v6' se refiere a una versión de la versión específica del sistema operativo original de Unix que se lanzó en 1975.

Todos los programas colocaron diagnósticos en la salida estándar. Esto siempre causó problemas cuando la salida se redirigió a un archivo, pero se volvió intolerable cuando la salida se envió a un proceso desprevenido. Sin embargo, no dispuestos a violar la simplicidad del modelo de entrada estándar-salida estándar, la gente toleró este estado de cosas a través de v6. Poco después, Dennis Ritchie cortó el nudo gordiano introduciendo el archivo de error estándar. Eso no fue suficiente. Con las tuberías, el diagnóstico podría provenir de cualquiera de varios programas que se ejecutan simultáneamente. Los diagnósticos necesarios para identificarse.
- Doug McIllroy, "Un lector de UNIX de investigación: Extractos anotados del Manual del programador, 1971-1986"

"Identificarse" significa simplemente decir "¡Hola! ¡Soy yo quien habla! Esto salió mal: [...]":

$ ls nothere
ls: nothere: No such file or directory

Hacer esto stderres preferible, ya que de lo contrario podría ser leído por lo que sea que esté leyendo stdout(pero no hacemos eso de lstodos modos , ¿ verdad ?).

Kusalananda
fuente
Entonces, cuando le preguntas al usuario algo mientras la aplicación se está ejecutando, ¿deberías imprimir la pregunta en stderr? Eso no suena bien. ¿Tienes una fuente para ello? ¿Esto solo se aplica a las aplicaciones que tienen una salida que no es solo preguntas y respuestas (salida que el usuario podría querer canalizar en algún lugar)?
UTF-8
@ UTF-8 ¿Debería el texto de la pregunta considerarse parte del resultado del programa? ¿Qué pasa con lo que escribe el usuario? No creo que deba ser (al igual que los proyectiles, no creo que deba ser). Pero tal vez depende de la aplicación?
Kusalananda
1
Gracias por tu edición. Mientras tanto, verifiqué el comportamiento de las aplicaciones estándar y se comportan como uno esperaría que se comportaran después de leer su respuesta.
UTF-8
@ UTF-8 puede encontrar estas preguntas y respuestas relevantes: unix.stackexchange.com/q/331611/22222
terdon
5

De las especificaciones POSIX para las transmisiones estándar:

Al inicio del programa, tres flujos deben estar predefinidos y no necesitan abrirse explícitamente: entrada estándar (para leer la entrada convencional), salida estándar (para escribir la salida convencional) y error estándar (para escribir la salida de diagnóstico ).

En otras palabras, los errores, la información de depuración y todo lo que cae en la categoría de diagnóstico entra stderr.

Consulte la pregunta relacionada para obtener más información: ¿Los informes de progreso / información de registro pertenecen a stderr o stdout?

Sergiy Kolodyazhnyy
fuente