Lo primero a tener en cuenta es que hay un par de formas dependiendo de su propósito y shell, por lo tanto, esto requiere una ligera comprensión de múltiples aspectos. Además, ciertos comandos como time
y strace
escriba 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 (suponiendo que sea un comando externo y no un shell incorporado) se crea a través de fork()
y execve()
llamadas al sistema, y antes de que eso suceda, otra llamada al sistema dup2()
realiza las redirecciones necesarias antes de execve()
suceder. En ese sentido, las redirecciones se heredan del shell padre. El m&>n
y m>n.txt
informar al shell sobre cómo realizar open()
y dup2()
syscall (véase también Cómo funciona la redirección de entradas, Cuál es la diferencia entre redirección y canalización, 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 parecidas a Bourne, tales 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 utilizan para la sesión interactiva. Difieren en sintaxis y características, pero afortunadamente para nosotros, la redirección de secuencias de errores funciona de la misma manera (excepto la &>
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 cosas clave a tener en cuenta: >
significa operador de redirección, donde abrimos un archivo y 2
integer significa descriptor de archivo stderr; de hecho, así es exactamente como el estándar POSIX para lenguaje de shell define la redirección en sección 2.7:
[n]redir-op word
Por simple >
redirección, el 1
el 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 entero o el operador de redirección no se pueden citar, de lo contrario, shell no los reconoce como tales y, en su lugar, los trata como una cadena de texto literal. En cuanto al espaciado, es importante que el 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 un comando típico en el shell sería
command [arg1] [arg2] 2> /dev/null
El truco aquí es que la redirección puede aparecer en cualquier lugar. Eso es a la vez 2> command [arg1]
y command 2> [arg1]
son válidos. Tenga en cuenta que para bash
shell, ahí existe &>
es una forma de redirigir los flujos stdout y stderr al mismo tiempo, pero de nuevo, es específico de bash y si está buscando la portabilidad de los scripts, puede que no funcione. Véase también Ubuntu Wiki y >>¿Cuál es la diferencia entre & y 2&1.
Nota: El >
operador de redirección truncar un archivo y lo sobrescribe, si el archivo existe. El 2>>
se puede utilizar para anexar stderr
file.
Si puede notar, >
está destinado a un solo comando. Para los scripts, podemos redirigir el flujo stderr de todo el script desde el exterior como en myscript.sh 2> /dev/null
o podemos hacer uso de ejecutivo incorporado. El ejecutivo incorporado tiene el poder de volver a cablear la transmisión para toda la sesión de shell, por así decirlo, ya sea de forma interactiva o mediante un script. Algo así como
#!/bin/shexec 2> ./my_log_file.txtstat /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 es a través de funciones. Como ceniciento como se señaló en su respuesta, podemos escribir una declaración de función con una 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
escriba su salida en stderr de forma predeterminada. En caso de time
comando, la única alternativa viable es redirigir la salida de todo el comando , es decir
time echo foo 2>&1 > file.txt
alternativamente, la lista síncrona o la subcapa podrían redirigirse si desea separar la salida ( como se muestra en post relacionado ):
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
Otros comandos, como strace
o dialog
proporcionar medios para redirigir stderr. strace
tener -o <filename.txt>
opción que permite especificar el nombre de archivo donde se debe escribir la salida. También hay una opción para escribir un archivo de texto para cada subproceso que strace
ver. El dialog
el comando escribe la interfaz de usuario de texto en stdout pero la salida en stderr, por lo que para guarde su salida en variable ( porque var=$(...)
y pipelines solo recibe stderr) necesitamos intercambiar los descriptores de archivo
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
pero, además, hay --output-fd
bandera, que también podemos utilizar. También existe el método de tuberías con nombre. Recomiendo leer el post enlazado sobre el dialog
comando para una descripción detallada de lo que está sucediendo.