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 teeutilidad 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 teeen la consola (esto es lo que teehace, 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 teepara 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_stuffobtendría lo que originalmente era el flujo de error estándar de utilitysus 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_stuffparte 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.logyutility 2>&1 | tee output.logesteeque duplica la transmisión. ¿Sería correcto?utility 2>&1 > output.log | more_stuffyutility >ouput.log| more_stuff, is the difference thatmore_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_stuffrecibiría lo queutilityoriginalmente se envió a su flujo de error (pero que se redirigió a la salida estándar). No porque terminaría en la consola simore_stuffno estuviera allí, sino porque va a la transmisión de salida estándar . En el segundo comando, nomore_stuffrecibe nada, ya que no hay salida estándar desde el lado izquierdo de la tubería. El flujo de error deutilitytodavía terminaría en la consola en el segundo comando.utility > output.log | more_stuffno 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.logsignifica 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.loges lo mismo con el2>&1bit, combina la salida estándar y el error estándar en la secuencia de salida estándar. Luego lo canaliza a través delteeprograma 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/stdoutal 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 directorymuestra 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 | teees 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 | teeera 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