Digamos que ejecuto un comando o script de shell, y me da salida. Sin conocer los aspectos internos de este comando o script de shell, ¿cómo se determina si el resultado proviene de stderr
o stdout
?
Por ejemplo,
$ ls -ld /
drwxrwxr-t 35 root admin 1258 Dec 11 19:16 /
vs
ls -ld /test
ls: /test: No such file or directory
¿Cómo puedo determinar si el primer comando se imprimió stdout
y el segundo en stderr
(¿lo hizo?)
io-redirection
KM.
fuente
fuente
stderred
en su entorno de shellLD_PRELOAD
para obtenerstdout
ystderr
en diferentes colores. Aquí hay una pregunta relacionada en ese sentido.Respuestas:
No hay forma de saber una vez que la salida ya se ha impreso. En este caso, tanto
stdout
ystderr
están conectados al terminal, por lo que la información sobre la cual corriente fue escrito para que ya se perdió en el momento en el texto apareció en su terminal; fueron combinados por el programa antes de llegar a la terminal.Lo que puede hacer, en un caso como el anterior, sería ejecutar el comando
stdout
ystderr
redirigirse a diferentes lugares y ver qué sucede. O ejecútelo dos veces, una vez constdout
redireccionado a/dev/null
y una vez constderr
redireccionado a/dev/null
, y vea cuál de esos casos da como resultado que aparezca el texto.Puede redirigir
stdout
a/dev/null
virando>/dev/null
en el extremo de la línea de comandos, y se puede redirigirstderr
a/dev/null
añadiendo2>/dev/null
.fuente
Puede redirigir stdout usando
> file
y redirigir stderr usando2> file
. Muchos shells modernos admiten la redirección a comandos, por lo que puede usarsed
para resaltar qué salida proviene de qué flujo:fuente
(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
El
annotate-output
script de Debian's ledevscripts
permite hacer esto selectivamente:La segunda columna indica stdout y stderr con
O
yE
respectivamente.Hay algunas advertencias, la principal es como se señaló en las otras respuestas: no puede hacer esto después del hecho. Ni el shell ni el terminal saben cómo un programa arbitrario utiliza sus descriptores de archivo, aunque el shell es responsable de configurarlos inicialmente.
Este método utiliza quince, escribir en un quince puede comportarse de manera diferente que escribir en un tty, y escribir en dos quince diferentes es definitivamente diferente (problemas potenciales de sincronización / intercalación). Además, no es adecuado para uso interactivo, por ejemplo,
annotate-output bash
no es un gran plan, pero es útil para muchos otros fines. Hay muchos, muchos ejemplos de scripts y funciones de shell en las respuestas a preguntas relacionadas sobre colorear stdin / stdout / stderr, el más robusto es stderrd, que utiliza la modificación en tiempo de ejecución de (la mayoría) de los programas para modificar los datos escritos en stderr.Esta pregunta a la que se vincula Anko tiene buenas respuestas sobre ese tema relacionado: colorear la salida stdout / stderr: ¿Puedo configurar mi shell para imprimir STDERR y STDOUT en diferentes colores?
fuente
bash
script que usawhile read
bucles y ejecuta undate
comando para cada línea de stdout o stderr, por lo que será mucho menos eficiente que elcmd > >(ts '%T O:') 2> >(ts '%T E:')
equivalente.Además de las otras respuestas, es interesante señalar
/proc/$PID/fd
(aunque no responde la pregunta):Como puede ver, aquí puede ver los descriptores de archivo abiertos para un proceso.
0
es elSTDIN
,1
es elSTDOUT
y2
es elSTDERR
. Si no tuviera el STDOUT o el STDERR redirigido, vería/dev/pts/33
(al menos en este ejemplo) porque apuntarían al terminal.notas :
/proc/$PID
solo existe para ejecutar procesos. En este caso lo he usadocat
sin argumentos para que no termine hasta que cierre elSTDIN
. También lo ejecuté en segundo plano, así que tengo el PID de inmediato por el bien de este ejemplo.fuente
No está muy claro lo que está preguntando, pero esto podría ayudar
Fuente
Si el código de salida es 0, simplemente significa que el comando se ejecuta correctamente (stdout), aquí puede encontrar significados si el código de salida es diferente de 0 (stderr)
fuente
stdout
y no implica cerostderr
?stderr
y devuelva un buen código de error, o escribastdout
y devuelva un código de error incorrecto. De hecho, intentefind /root
, suponiendo que no se esté ejecutando como root, debería imprimir 2 líneas: se imprime "/ root" y se imprimestdout
"find: / root: Permiso denegado"stderr
. Y find devuelve un código de retorno incorrecto.Por lo general, STDERR tendrá el nombre del programa antepuesto al mensaje con dos puntos.
Ejemplo:
Vs
fuente
Para capturar y probar la salida de error:
fuente