Indique de inmediato qué salida se envió a stderr


8

Al automatizar una tarea, es sensato probarla primero manualmente. Sin embargo, sería útil si los datos que van a stderr se reconocen inmediatamente como tales, y se distinguen de los datos que van a stdout, y tienen todos los resultados juntos para que sea obvio cuál es la secuencia de eventos.

Un último toque que sería bueno es que, al salir del programa, imprima su código de retorno.

Todas estas cosas ayudarían en la automatización. Sí, puedo hacer eco del código de retorno cuando finaliza un programa, y ​​sí, puedo redirigir stdout y stderr; lo que realmente me gustaría es un shell, script o redirector fácil de usar que muestra stdout en negro, muestra stderr entrelazado en rojo e imprime el código de salida al final.

¿Hay tal bestia? [Si es importante, estoy usando Bash 3.2 en Mac OS X].


Actualización : lo siento, han pasado meses desde que vi esto. Se me ocurrió un script de prueba simple:

#!/usr/bin/env python
import sys

print "this is stdout"
print >> sys.stderr, "this is stderr"
print "this is stdout again"

En mis pruebas (y probablemente debido a la forma en que se almacenan las cosas), rse e hilite muestran todo desde stdout y luego todo desde stderr. El método fifo obtiene el orden correcto pero parece colorear todo siguiendo la línea stderr. ind se quejó de mis líneas stdin y stderr, y luego puso el resultado de stderr al final.

La mayoría de estas soluciones son viables, ya que no es atípico que solo el último resultado vaya a stderr, pero aún así, sería bueno tener algo que funcionó un poco mejor.


Si eres flojo (o tienes dolor en los dedos) como yo, puedes tomar una subshell con las soluciones a continuación (por ejemplo, rse zsh) y ahora todos los comandos colorean stderr.
sesgo

Respuestas:


3

También puede consultar stderred: https://github.com/sickill/stderred


Desafortunadamente, stderred rompe "abrir" y "mvim" para usuarios de Mac como el OP.
AlcubierreDrive

Esto funciona muy bien y obtiene el orden de salida de la manera correcta debido a la forma en que funciona. Configúrelo una vez, actívelo en su perfil, y recibirá mensajes rojos cada vez que se escriba en stderr.
Clinton Blackmore


9

Acabo de idear un método loco que involucra FIFOs.

$ mkfifo foo
$ grep --color . foo &
$ your_command 2>foo

Si desea que la salida stderr se separe, puede abrir dos shells separados y ejecutar " grep --color . foo" en uno sin el &, luego ejecutar el comando en el otro (aún con el 2>foo). Obtendrá el stderr en el grepuno y el stdout en el principal.

Esto funciona porque la salida stderr se enruta a través de FIFO grep --color, cuyo color predeterminado es rojo (al menos es para mí). Cuando haya terminado, solo rmel FIFO ( rm foo).

Advertencia : Realmente no estoy seguro de cómo manejará el orden de salida, tendrá que probarlo.


Eso es bastante hábil.
Clinton Blackmore

7

Si, esto es posible. Mire la sección "Hacer STDERR rojo" en este sitio para un ejemplo de trabajo.

El código básico es este

# Red STDERR
# rse <command string>
function rse()
{
    # We need to wrap each phrase of the command in quotes to preserve arguments that contain whitespace
    # Execute the command, swap STDOUT and STDERR, colour STDOUT, swap back
    ((eval $(for phrase in "$@"; do echo -n "'$phrase' "; done)) 3>&1 1>&2 2>&3 | sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/") 3>&1 1>&2 2>&3
}

Se da una breve explicación en la función misma. Lo que hace es mover STDOUT y STDERR, por lo que sed obtiene STDERR en 1, lo colorea y luego lo intercambia. Piense en la secuencia de archivos 3 como una variable temporal aquí.

La llamada es bastante simple

rse commands

Sin embargo, ciertas invocaciones no funcionarán como se esperaba; Las advertencias se proporcionan en la página vinculada.

Por cierto, creo que también es posible llegar con una solución de la forma

commands | rse 

donde rse coloreará la salida.

También encontré este proyecto hilite que parece hacer esto. No lo he probado, pero podría ser lo que estás buscando.

hilite es una pequeña utilidad que ejecuta el comando que especifique, resaltando todo lo impreso en stderr. Está diseñado principalmente para su uso con compilaciones, para hacer que las advertencias y errores sobresalgan como un cliché doloroso.

Otros proyectos relacionados:


rse e hilite están bastante cerca de lo que quiero.
Clinton Blackmore

1

Otro programa es ind:

http: // www.habets.pp.se/synscan/programs.php?prog=ind (debe ensamblar el hipervínculo usted mismo, no tengo suficientes puntos para más de uno por respuesta). Hay una captura de pantalla e incluso un screencast allí.

Ejecuta el subproceso en un pie, que los demás probablemente no. Esto puede importar donde importa el orden (a menudo lo hace), ya que stderr se vacía inmediatamente en los terminales y stdout está completamente protegido cuando no es un tty.

Para una explicación completa, vea esto: http://blog.habets.pp.se/2008/06/Buffering-in-pipes

Además, ind trabaja con programas interactivos y personajes de control. Bash funciona de manera normal cuando se inicia con "ind bash -i".

Esto podría funcionar para darle colores mientras conserva Ctrl-P et.al.

ind -P $(echo -ne '\033[31;1m') -p $(echo -ne '\033[0m') bash -i

1

Aquí hay muchas respuestas para resaltar la salida stderr todavía. Solo puedo agregar uno bastante fácil: en una fila, que adjuntas al comando:

command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m"; done)

Pero debe agregar esto después del comando cada vez.

Personalmente, me gusta la posibilidad mencionada por @nagul, la función rse agregada a bashrc.

Pero quiero agregar la solución para imprimir el código de salida. Puede agregar este valor al comienzo de su fila de solicitud de bash:

hostname$ command
  Some error occurred. Returned exit code.
EC hostname$

Donde EC es el código de salida del comando.

Lo tengo configurado en el camino, que cuando el código de salida es 0, no se imprimirá, pero cualquier otro valor se imprimirá antes del próximo mensaje en color rojo.

Todo el truco se hace en ~ / .bashrc:

my_prompt() {
 EXITSTATUS="$?"
 RED="\[\033[1;31m\]"
 OFF="\[\033[m\]"

PROMPT="${debian_chroot:+($debian_chroot)}\h \$ "

if [ "${EXITSTATUS}" -eq 0 ]; then
   PS1="${PROMPT}"
else
   PS1="${RED}$EXITSTATUS${OFF} ${PROMPT}"
fi
}

PROMPT_COMMAND=my_prompt

La línea de solicitud está definida por defecto por la variable PS1. Copie lo que tenga aquí en la variable PROMPT y luego cree la variable PS1 con o sin código de salida.

Bash mostrará la información en la variable PS1 en la solicitud.


Esto es exactamente lo que estaba buscando, ¡gracias!
Dylon

1

hay annotate-outpututilidad ( devscriptspaquete Debian), si desea hacerlo sin colores

$ annotate-output /tmp/test.py    
14:24:57 I: Started /tmp/test.py
14:24:57 E: this is stderr
14:24:57 O: this is stdout
14:24:57 O: this is stdout again
14:24:57 I: Finished with exitcode 0
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.