Mirando los dos comandos por separado:
utility 2>&1 >output.log
Aquí, dado que las redirecciones se procesan de izquierda a derecha, el flujo de error estándar primero se redirigirá a donde quiera que vaya el flujo de salida estándar (posiblemente a la consola), y luego el flujo de salida estándar se redirigirá a un archivo. La secuencia de error estándar no se redirigiría a ese archivo.
El efecto visible de esto sería que obtienes lo que se produce en un error estándar en la pantalla y lo que se produce en la salida estándar en el archivo.
utility 2>&1 | tee output.log
Aquí, redirige el error estándar al mismo lugar que la secuencia de salida estándar. Esto significa que ambas secuencias se canalizarán a la tee
utilidad como una única secuencia de salida entremezclada y que estos datos de salida estándar se guardarán en el archivo dado tee
. Los datos también se reproducirían tee
en la consola (esto es lo que tee
hace, duplica los flujos de datos).
Cualquiera de estos que se use depende de lo que le gustaría lograr.
Tenga en cuenta que no podrá reproducir el efecto de la segunda tubería con solo >
(como en utility >output.log 2>&1
, lo que ahorraría tanto la salida estándar como el error en el archivo). Debería usarlo tee
para obtener los datos en la consola, así como en el archivo de salida.
Notas adicionales:
El efecto visible del primer comando,
utility 2>&1 >output.log
sería lo mismo que
utility >output.log
Es decir, la salida estándar va al archivo y el error estándar va a la consola.
Sin embargo, si se agrega un paso de procesamiento adicional al final de cada uno de los comandos anteriores, habría una gran diferencia:
utility 2>&1 >output.log | more_stuff
utility >output.log | more_stuff
En la primera tubería, more_stuff
obtendría lo que originalmente era el flujo de error estándar de utility
sus datos de entrada estándar, mientras que en la segunda tubería, dado que es solo el flujo de salida estándar resultante que se envía a través de una tubería, la more_stuff
parte de la tubería no obtendría nada para leer en su entrada estándar.
utility 2>&1 | tee output.log
, ¿quiere decir que dado que 1 se dirige a tee, también lo es 2. Como tee duplica la transmisión, la salida se muestra en la consola y se escribe en el archivo? De ahí la diferencia entreutility 2>&1 > output.log
yutility 2>&1 | tee output.log
estee
que duplica la transmisión. ¿Sería correcto?utility 2>&1 > output.log | more_stuff
yutility >ouput.log
| more_stuff, is the difference that
more_stuff` tiene la salida de error estándar a la consola como entradamore_stuff
? Dado que en el segundo ejemplo, no hay salida para la consola, esencialmente no hay entrada paramore_stuff
? En caso afirmativo, eso no está claro ya que en el párrafo anterior observa que la salida estándar va al archivo y el error estándar va a la consola.more_stuff
recibiría lo queutility
originalmente se envió a su flujo de error (pero que se redirigió a la salida estándar). No porque terminaría en la consola simore_stuff
no estuviera allí, sino porque va a la transmisión de salida estándar . En el segundo comando, nomore_stuff
recibe nada, ya que no hay salida estándar desde el lado izquierdo de la tubería. El flujo de error deutility
todavía terminaría en la consola en el segundo comando.utility > output.log | more_stuff
no produce una salida en la secuencia de salida estándar desde un punto de vista de error estándar?Nota editorial
Asegúrese de leer los comentarios sobre esta respuesta : derobert .
Respuesta original
2>&1 >output.log
significa primero comenzar a enviar todas las cosas del identificador de archivo 2 (error estándar) al identificador de archivo 1 (salida estándar) y luego enviarlo al archivooutput.log
. En otras palabras, envíe un error estándar y una salida estándar al archivo de registro.2>&1 | tee output.log
es lo mismo con el2>&1
bit, combina la salida estándar y el error estándar en la secuencia de salida estándar. Luego lo canaliza a través deltee
programa que enviará su entrada estándar a su salida estándar (comocat
) y también al archivo. Por lo tanto, combina las dos secuencias (error y salida), luego las envía al terminal y al archivo.La conclusión es que el primero envía
stderr
/stdout
al archivo, mientras que el segundo lo envía tanto al archivo como a la salida estándar (que probablemente sea el terminal a menos que esté dentro de otra construcción que haya redirigido la salida estándar).Menciono esa última posibilidad porque puedes tener cosas como:
donde nada termina en la terminal.
fuente
cat /doesnotexist 2>&1 >output.txt
: verá que secat: /doesnotexist: No such file or directory
muestra en el terminal y output.txt es un archivo vacío. El orden de precedencia y el cierre están en juego:2>&1
(dup fd2 del fd1 actual ), luego>output.txt
(redirige fd1 a output.txt, sin cambiar nada más). La razón que2>&1 |
es diferente es por el orden de precedencia:|
antes>
.El primer comando hará la otra tarea:
Después
el STDOUT anterior se guardará (copiará) en STDERR y luego STDOUT se redirigirá al archivo.
Entonces, stdout irá al archivo y stderr irá a la consola.
Y en
ambas transmisiones serán redirigidas a tee. Tee duplicará cualquier entrada a su stdout (la consola en su caso) y al archivo (
output.log
).Y hay otra forma de primero:
esto redirigirá tanto STDOUT como STDERR al archivo.
fuente
El primero solo se envía al archivo. El segundo sale tanto al archivo como a la pantalla.
fuente
La razón
2>&1 | tee
es poder capturar stdout y stderr en un archivo de registro y verlo en la pantalla al mismo tiempo. Esto también podría hacerse>output.txt 2>&1 & tail -f
, pero no sabría cuándo finalizó el comando de fondo: si el programa finalizó o si se ejecuta sin salida. El2>&1 | tee
era un idioma común para los programadores.fuente
Veamos primero un código de muestra:
Vamos a comparar los resultados:
./helloerror
+ archivo: sin mensaje; consola: mensaje 1,2,3;
./helloerror >error.txt
+ archivo: mensaje 1,2; consola: mensaje 3;
./helloerror 2>&1 >error.txt
+ archivo: mensaje 1,2; consola: mensaje 3;
+ igual que ./helloerror> error.txt
./helloerror >error.txt 2>&1
+ archivo: mensaje 3,1,2; consola: sin mensaje;
+ tenga en cuenta que el orden 3 es primero, luego 1, luego 2
./helloerror | tee error.txt 2>&1
+ archivo: mensaje 1,2; consola: mensaje 3,1,2;
+ tenga en cuenta que el orden 3 es primero, luego 1, luego 2
./helloerror 2>&1 | tee error.txt
+ archivo: mensaje 3,1,2; consola: mensaje 3,1,2;
Para usar:
./helloerror >error.txt 2>&1
-> si uno quiere todos los mensajes (stdout + stderr) en el archivo, pero no anclado en la consola
./helloerror 2>&1 | tee error.txt
-> si uno quiere todos los mensajes (stdout + stderr) en el archivo e impresos en la consola
fuente
Aquí hay una publicación que resume las secuencias de salida de Unix: http://www.devcodenote.com/2015/04/unix-output-streams.html
Un fragmento de la publicación:
Hay 3 flujos de salida estándar:
fuente