¿Cómo redirigir y agregar stdout y stderr a un archivo con Bash?


1535

Para redirigir stdout a un archivo truncado en Bash, sé usar:

cmd > file.txt

Para redirigir stdout en Bash, agregando a un archivo, sé usar:

cmd >> file.txt

Para redirigir stdout y stderr a un archivo truncado, sé usar:

cmd &> file.txt

¿Cómo redirijo stdout y stderr anexando a un archivo? cmd &>> file.txtno funciono para mi


37
Me gustaría señalar que &> outfile es un código específico de Bash (y otros) y no portátil. La forma de ser portátil (similar a las respuestas adjuntas) siempre fue y sigue siendo> outfile 2> & 1
— TheBonsai

Respuestas:


1999
cmd >>file.txt 2>&1

Bash ejecuta las redirecciones de izquierda a derecha de la siguiente manera:

  1. >>file.txt: Abrir file.txten modo agregar y redirigir stdoutallí.
  2. 2>&1: Redireccionar stderra "a dónde stdoutva actualmente" . En este caso, ese es un archivo abierto en modo anexar. En otras palabras, &1reutiliza el descriptor de archivo que stdoutusa actualmente.

33
¡Funciona genial! pero ¿hay alguna manera de darle sentido a esto o debería tratar esto como una construcción atómica de bash?
— flybywire

181
Es una redirección simple, las declaraciones de redirección se evalúan, como siempre, de izquierda a derecha. >> archivo: rojo. STDOUT a archivo (modo de agregado) (abreviatura de 1 >> archivo) 2> & 1: Rojo. STDERR a "donde va stdout" Tenga en cuenta que la interpretación "redirigir STDERR a STDOUT" es incorrecta.
— TheBonsai

31
Dice "agregar salida (stdout, descriptor de archivo 1) en file.txt y enviar stderr (descriptor de archivo 2) al mismo lugar que fd1".
— Pausado hasta nuevo aviso.

2
@TheBonsai sin embargo, ¿qué pasa si necesito redirigir STDERR a otro archivo pero anexar? ¿es posible?
— arod

41
si lo haces cmd >>file1 2>>file2deberías lograr lo que quieres.
— Woodrow Douglass

367

Hay dos formas de hacer esto, dependiendo de su versión de Bash.

La forma clásica y portátil ( Bash pre-4 ) es:

cmd >> outfile 2>&1

Una forma no portátil, comenzando con Bash 4 es

cmd &>> outfile

(análogo a &> outfile)

Para un buen estilo de codificación, debes

  • decida si la portabilidad es una preocupación (luego use la forma clásica)
  • decida si la portabilidad incluso para Bash pre-4 es una preocupación (luego use la forma clásica)
  • no importa qué sintaxis use, no la cambie dentro del mismo script (¡confusión!)

Si su script ya comienza con #!/bin/sh(sin importar si fue intencionado o no), entonces la solución Bash 4, y en general cualquier código específico de Bash, no es el camino a seguir.

También recuerde que Bash 4 &>>es una sintaxis más corta: no introduce ninguna funcionalidad nueva ni nada por el estilo.

La sintaxis es (además de otra sintaxis de redirección) descrita aquí: http://bash-hackers.org/wiki/doku.php/syntax/redirection#appending_redirected_output_and_error_output


8
Prefiero & >> ya que es consistente con &> y >>. También es más fácil leer "agregar salida y errores a este archivo" que "enviar errores a la salida, agregar salida a este archivo". Nota mientras que Linux tiene en general una versión actual de fiesta, OS X, en el momento de la escritura, aún requiere de fiesta de 4 a instalado manualmente a través de homebrew etc
— mikemaccana

Me gusta más porque es más corto y solo tiene Tweoi lugares por línea, entonces, ¿qué haría, por ejemplo, zsh con "& >>"?
— Phillipp

También es importante tener en cuenta que en un trabajo cron, debe usar la sintaxis anterior a 4, incluso si su sistema tiene Bash 4.
— hyperknot

55
@zsero cron no usa bash en absoluto ... lo usa sh. Puede cambiar el shell predeterminado anteponiendo SHELL=/bin/bashal crontab -earchivo.
— Ray Foss

89

En Bash también puede especificar explícitamente sus redireccionamientos a diferentes archivos:

cmd >log.out 2>log_error.out

Anexar sería:

cmd >>log.out 2>>log_error.out

66
Redirigir dos secuencias al mismo archivo usando su primera opción hará que la primera escriba "encima" de la segunda, sobrescribiendo algunos o todos los contenidos. Use cmd >> log.out 2> log.out en su lugar.
— Orestis P.

3
Gracias por atrapar eso; tienes razón, uno golpeará al otro. Sin embargo, su comando tampoco funciona. Creo que la única forma de escribir en el mismo archivo es como se ha dado anteriormente cmd >log.out 2>&1. Estoy editando mi respuesta para eliminar el primer ejemplo.
— Aaron R.

65

En Bash 4 (así como ZSH 4.3.11):

cmd &>>outfile

recién salido de la caja


2
@todos: esta es una buena respuesta, ya que funciona con bash y es breve, por lo que he editado para asegurarme de que menciona bash explícitamente.
— mikemaccana

10
@mikemaccana: la respuesta de TheBonsai muestra la solución bash 4 desde 2009
— jfs

52

Esto debería funcionar bien:

your_command 2>&1 | tee -a file.txt

Almacenará todos los registros en file.txt y los volcará en la terminal.


Esta es la respuesta correcta si también desea ver la salida en el terminal. Sin embargo, esta no fue la pregunta que se hizo originalmente.
— Mikko Rantalainen

25

Prueba esto

You_command 1>output.log  2>&1

Su uso de &> x.file funciona en bash4. lo siento por eso : (

Aquí vienen algunos consejos adicionales.

0, 1, 2 ... 9 son descriptores de archivos en bash.

0 representa stdin, 1 representa stdout, 2 representa stderror. 3 ~ 9 es de repuesto para cualquier otro uso temporal.

Cualquier descriptor de archivo se puede redirigir a otro descriptor de archivo o archivo mediante el operador >o >>(agregar).

Uso: < file_descriptor > > < nombre de archivo | & file_descriptor >

Por favor refiérase a http://www.tldp.org/LDP/abs/html/io-redirection.html


Su ejemplo hará algo diferente a lo que solicitó el OP: redirigirá el stderr de You_commandstdout y el stdout de You_commandal archivo output.log. Además, no se agregará al archivo pero lo sobrescribirá.
— pabouk

Correcto: el descriptor de archivo podría ser cualquier valor que sea más de 3 para todos los demás archivos.
— Itachi

55
Su respuesta muestra el error de redirección de salida más común: redirigir STDERR a donde STDOUT está apuntando actualmente y solo después de eso redireccionar STDOUT al archivo. Esto no hará que STDERR se redirija al mismo archivo. El orden de las redirecciones es importante.
— Jan Wikholm

1
significa, primero debería redirigir STDERROR a STDOUT, luego redirigir STDOUT a un archivo. 1 > output.log 2>&1
— Quintus.Zhou

1
@ Quintus.Zhou Yup. Su versión redirige err hacia fuera y, al mismo tiempo, hacia fuera para archivar.
— Alex Yaroshevich

11

Me sorprende que en casi diez años, nadie haya publicado este enfoque todavía:

Si usa versiones anteriores de bash donde &>>no está disponible, también puede hacer:

(cmd 2>&1) >> file.txt

Esto genera un subshell, por lo que es menos eficiente que el enfoque tradicional cmd >> file.txt 2>&1y, en consecuencia, no funcionará para los comandos que necesitan modificar el shell actual (por ejemplo cd, pushd), pero este enfoque me parece más natural y comprensible:

  1. Redirigir stderr a stdout.
  2. Redireccione la nueva stdout agregando a un archivo.

Además, los paréntesis eliminan cualquier ambigüedad de orden, especialmente si desea canalizar stdout y stderr a otro comando.


Esta implementación provoca un proceso adicional para que el sistema se ejecute. El uso de la sintaxis cmd >> file 2>&1funciona en todos los shells y no necesita un proceso adicional para ejecutarse.
— Mikko Rantalainen

@MikkoRantalainen Ya expliqué que genera una subshell y es menos eficiente. El objetivo de este enfoque es que si la eficiencia no es un gran problema (y rara vez lo es), de esta manera es más fácil de recordar y más difícil equivocarse.
— jamesdlin
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.