Nuestro grupo de trabajo ha pasado mucho tiempo buscando soluciones a tus dudas, te compartimos la soluciones y esperamos que te resulte de mucha ayuda.
Solución:
Hay dos flujos de salida principales en Linux (y otros sistemas operativos), salida estándar (stdout) y error estándar (stderr). Los mensajes de error, como los que muestra, se imprimen con error estándar. El operador de redirección clásico (command > file
) solo redirige la salida estándar, por lo que el error estándar aún se muestra en el terminal. Para redirigir stderr también, tiene algunas opciones:
-
Redirigir stdout a un archivo y stderr a otro archivo:
command > out 2>error
-
Redirigir stdout a un archivo (
>out
), y luego redirigir stderr a stdout (2>&1
):command >out 2>&1
-
Redirigir ambos a un archivo (esto no es compatible con todos los shells,
bash
yzsh
apoyarlo, por ejemplo, perosh
yksh
no):command &> out
Para obtener más información sobre los distintos operadores de control y redirección, consulte aquí.
Lo primero que debe tener en cuenta es que hay un par de formas dependiendo de su propósito y caparazón, por lo tanto, esto requiere una ligera comprensión de múltiples aspectos. Además, ciertos comandos como time
y strace
escribe la salida en stderr de forma predeterminada, y puede o no proporcionar un método de redirección específico para ese comando
La teoría básica detrás de la redirección es que un proceso generado por shell (asumiendo que es un comando externo y no integrado en el shell) se crea a través de fork()
y execve()
syscalls, y antes de que suceda otra syscall dup2()
realiza las redirecciones necesarias antes execve()
sucede. En ese sentido, las redirecciones se heredan del shell padre. los m&>n
y m>n.txt
informar al caparazón sobre cómo realizar open()
y dup2()
syscall (consulte también Cómo funciona la redirección de entrada, cuál es la diferencia entre redirección y tubería, y qué significa exactamente & en la redirección de salida)
Redirecciones de shell
Lo más típico es a través de 2>
en conchas tipo Bourne, como dash
(que está enlazado simbólicamente a /bin/sh
) y bash
; el primero es el shell predeterminado y compatible con POSIX y el otro es el que la mayoría de los usuarios usan para la sesión interactiva. Se diferencian en sintaxis y características, pero afortunadamente para nosotros, la redirección del flujo de errores funciona igual (excepto que &>
uno no estándar). En el caso de csh y sus derivados, la redirección stderr no funciona del todo allí.
Volvamos a 2>
parte. Dos key cosas a notar: >
significa operador de redirección, donde abrimos un archivo y 2
entero significa descriptor de archivo stderr; de hecho, así es exactamente como el estándar POSIX para el lenguaje shell define la redirección en la sección 2.7:
[n]redir-op word
Por simple >
redirección, la 1
entero está implícito para stdout
, es decir echo Hello World > /dev/null
es lo mismo que echo Hello World 1>/dev/null
. Tenga en cuenta que el operador entero o de redirección no se puede citar; de lo contrario, el shell no los reconoce como tales y, en su lugar, los trata como literales. string de texto. En cuanto al espaciado, es importante que el número entero esté justo al lado del operador de redirección, pero el archivo puede estar al lado del operador de redirección o no, es decir command 2>/dev/null
y command 2> /dev/null
funcionará bien.
La sintaxis algo simplificada para el comando típico en shell sería
command [arg1] [arg2] 2> /dev/null
El truco aquí es que la redirección puede aparecer en cualquier lugar. Eso es ambos 2> command [arg1]
y command 2> [arg1]
son validos. Tenga en cuenta que para bash
cáscara, existe &>
forma de redirigir las transmisiones stdout y stderr al mismo tiempo, pero de nuevo, es específico de bash y si se está esforzando por la portabilidad de los scripts, es posible que no funcione. Consulte también Ubuntu Wiki y Cuál es la diferencia entre &> y 2> & 1.
Nota: los >
operador de redirección trunca un archivo y lo sobrescribe, si el archivo existe. los 2>>
puede usarse para agregar stderr
archivar.
Si puede notar, >
está destinado a un solo comando. Para los scripts, podemos redirigir el flujo stderr de todo el script desde afuera como en myscript.sh 2> /dev/null
o podemos hacer uso de exec incorporado. El ejecutivo integrado tiene el poder de volver a cablear el flujo de toda la sesión de shell, por así decirlo, ya sea de forma interactiva o mediante un script. Algo como
#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file
En este ejemplo, el archivo de registro debería mostrar stat: cannot stat '/etc/non_existing_file': No such file or directory
.
Otra forma más es a través de funciones. Como señaló kopciuszek en su respuesta, podemos escribir una declaración de función con la redirección ya adjunta, es decir
some_function()
command1
command2
2> my_log_file.txt
Comandos que escriben en stderr exclusivamente
Comandos como time
y strace
escribe su salida en stderr por defecto. En caso de time
comando, la única alternativa viable es redirigir la salida del comando completo, es decir
time echo foo 2>&1 > file.txt
alternativamente, la lista síncrona o la subcapa se pueden redirigir si desea separar la salida (como se muestra en la publicación relacionada):
time sleep 1 2> sleep.stderr ; 2> time.txt
Otros comandos, como strace
o dialog
proporcionar medios para redirigir stderr. strace
tiene -o
opción que permite especificar el nombre del archivo donde se debe escribir la salida. También hay una opción para escribir un archivo de texto para cada subproceso que strace
ve. los dialog
El comando escribe la interfaz de usuario de texto en stdout pero la salida en stderr, por lo que para guardar su salida en la variable (porque var=$(...)
y las canalizaciones solo reciben stderr) necesitamos intercambiar los descriptores de archivo
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
pero además, hay --output-fd
flag, que también podemos utilizar. También existe el método de canalizaciones con nombre. Recomiendo leer la publicación vinculada sobre el dialog
comando para una descripción completa de lo que está sucediendo.
Comentarios y puntuaciones del artículo
Recuerda algo, que tienes la capacidad de valorar este post si te fue útil.