Cuándo usar la redirección a stderr en scripts de shell

15

Sé que las utilidades con buen comportamiento como grep generan mensajes "normales" a stdout y mensajes de error a stderr.

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

Cuando escribo scripts de shell, a menudo me resulta difícil decidir qué salida y qué mensajes debo presentar en stderr, o si debo molestarme.

Me gustaría saber acerca de las buenas prácticas: ¿cuándo es razonable y razonable enviar un mensaje a stderr y cuándo no?

"Depende", claro, pero ¿tiene alguna idea que me ayudaría a tomar estas decisiones?

Para que esta pregunta subjetiva se ajuste al formato, me gustaría alentar respuestas que aborden el "por qué", y que estén informadas por la experiencia y, si es posible, respaldadas por hechos.

glts
fuente
@rush lo explica perfectamente. Generalmente imprimo informes de progreso en stderr para secuencias de comandos largas.
terdon

Respuestas:

12

Cuando escribo scripts de shell, a menudo me resulta difícil decidir qué salida y qué mensajes debo presentar en stderr, o si debo molestarme.

El silencio es oro. No genera nada si todo está bien.

Me gustaría saber acerca de las buenas prácticas: ¿cuándo es razonable y razonable enviar un mensaje a stderr y cuándo no?

La forma más fácil de separar stderr de stdout: solo imagine que toda la salida de sus scripts será redirigida a otro comando a través de pipe. En ese caso, debe mantener todas las notificaciones en stderr, ya que dicha información inesperada en stdout puede romper la secuencia de la tubería.

También a veces en tuberías como esta:

command1 | while read line ; do command2 ; done | command3

necesita pasar algo de la command2salida de los usuarios. La forma más fácil sin archivos temporales es stderr.

prisa
fuente
Gracias por la idea de "imaginar una pipa". A veces he desplegado scripts que no hacen más que "notificar" ( echoalgunas variables, mostrar lo que se ha hecho, mostrar el progreso). Dudo en poner todo en stderr ya que estos mensajes de registro son todo lo que el script generará. No estoy seguro de cómo aplicar la idea de tubería en estas situaciones.
glts
1
Los programas de @glts siempre se modifican y mejoran. Si bien las secuencias de comandos que menciona no generan ningún dato ahora, podrían hacerlo más tarde o puede usarlas como puntos de partida para otras secuencias de comandos que sí lo hacen. Si sigues la convención para empezar, obtendrás muchas menos sorpresas más adelante. OTOH, si solo desea guardar la salida en un archivo, entonces debe redirigir stderr, por lo que es una compensación como todo lo demás.
Joe
+1 Otra paráfrasis: asegúrese de que stdout sea siempre legible por máquina, o al menos contenga datos de texto útiles en un formato consistente.
tripleee
2

Generalmente escribo todo lo relacionado con la operación de la aplicación stderr, stdoutestá reservado para datos.

Imagina una aplicación como cat. Cuando lo usa para leer la entrada y pasarla a otra aplicación (a través de una tubería), no desea que la salida esté llena de mensajes de estado.

Todo lo que pueda ser interesante para otra aplicación o un postprocesador para mi aplicación stdout, todo lo que solo se relaciona con el interno de mi aplicación lo hará stderr.

Der Hochstapler
fuente
0

Mi preferencia personal es enviar mensajes de error y excepciones stderry mensajes informativos a stdout. OMI, stderres para cualquier excepción y, por lo tanto, mi convención.

unxnut
fuente