En un shell de Unix, si quiero combinar stderr
y stdout
en la stdout
secuencia para una mayor manipulación, puedo agregar lo siguiente al final de mi comando:
2>&1
Entonces, si quiero usar head
en la salida de g++
, puedo hacer algo como esto:
g++ lots_of_errors 2>&1 | head
así que solo puedo ver los primeros errores.
Siempre tengo problemas para recordar esto, y constantemente tengo que buscarlo, y es principalmente porque no entiendo completamente la sintaxis de este truco en particular.
¿Alguien puede romper esto y explicar carácter por carácter qué 2>&1
significa?
2>&1
que 2> / dev / null ;-)|&
es una forma abreviada de2>&1 |
si estás usando zsh. No puedo hablar sobre si eso se aplica a otros proyectiles tipo bourne o si es una característica de solo zsh.Respuestas:
El descriptor de archivo 1 es la salida estándar (
stdout
).El descriptor de archivo 2 es el error estándar (
stderr
).Esta es una manera de recordar este constructo (aunque no es del todo exacto): en un primer momento,
2>1
puede parecer una buena manera de redirigirstderr
astdout
. Sin embargo, en realidad se interpretará como "redirigirstderr
a un archivo llamado1
".&
indica que lo que sigue es un descriptor de archivo y no un nombre de archivo. Por lo que la construcción se convierte en:2>&1
.fuente
&2>&1
?&
solo se interpreta como "descriptor de archivo" en el contexto de las redirecciones. La escrituracommand &2>&
se analiza comocommand &
y2>&1
, es decir, "ejecutacommand
en segundo plano, luego ejecuta el comando2
y redirige su stdout a su stdout".2>'&1'
redirecciona stdout a
afile.txt
. Esto es lo mismo que hacerPara redirigir stderr, debes hacer lo siguiente:
>&
es la sintaxis para redirigir una secuencia a otro descriptor de archivo: 0 es stdin, 1 es stdout y 2 es stderr.Puede redirigir stdout a stderr haciendo:
O viceversa:
Entonces, en resumen ...
2>
redirige stderr a un archivo (no especificado), agregando&1
redirige stderr a stdout.fuente
java ... 2&1 >> data.log
? Vi que uno de mis colegas hizo esto.cmd 2>&1 >> somefile.log
agregará stdout / stderr a un archivo; es básicamente lo mismo que el anterior, con>> file
agregarcmd 2>&1 >>file
no redirige stderr al archivo, pero locmd >> file 2>&1
hace. El orden importa. En el primer caso, stderr se redirige al stdout del shell (posiblemente un tty si el comando se ingresa de manera interactiva), y luego stdout se dirige al archivo. En el segundo caso, stdout se dirige al archivo y luego stderr se dirige al mismo lugar.0(or 1,2)>&0(or 1,2)
como una opción para controlar la salida? Esecho test >test.log 2>&1
igual queecho test 2>&1 >test.log
?Algunos trucos sobre redireccionamiento
Algunas particularidades de sintaxis sobre esto pueden tener comportamientos importantes. Hay algunas pequeñas muestras sobre redirecciones,
STDERR
,STDOUT
, y los argumentos de pedidos .1 - ¿Sobrescribir o anexar?
Símbolo de redirección
>
media .>
significa enviar a como un archivo completo completo , sobrescribiendo el objetivo si existe (vea lanoclobber
función bash en el # 3 más adelante).>>
significa enviar además de agregaría al objetivo si existe.En cualquier caso, el archivo se crearía si no existiera.
2 - ¡La línea de comando de shell depende del orden!
Para probar esto, necesitamos un comando simple que envíe algo en ambas salidas :
(Esperando que no tenga un directorio llamado
/tnt
, por supuesto;). Bueno, lo tenemos !!Entonces, veamos:
La última línea de comando volca
STDERR
a la consola, y parece que no es el comportamiento esperado ... Pero ...Si desea realizar un filtrado posterior sobre una salida, la otra o ambas:
Tenga en cuenta que la última línea de comando en este párrafo es exactamente la misma que en el párrafo anterior, donde escribí parece no ser el comportamiento esperado (por lo tanto, esto podría incluso ser un comportamiento esperado).
Bueno, hay algunos pequeños trucos sobre las redirecciones, para realizar diferentes operaciones en ambas salidas :
Nota: el
&9
descriptor ocurriría espontáneamente debido a) 9>&2
.Anexo: nota!Con la nueva versión degolpetazo(
>4.0
) hay una nueva característica y una sintaxis más sexy para hacer este tipo de cosas:Y finalmente para un formato de salida en cascada de este tipo:
Anexo: nota! La misma sintaxis nueva, en ambos sentidos:
Donde
STDOUT
pasar por un filtro específico,STDERR
a otro y finalmente ambas salidas fusionadas pasan por un tercer filtro de comando.3 - Una palabra sobre
noclobber
opción y>|
sintaxisEso se trata de sobrescribir :
Si bien le
set -o noclobber
indica a bash que no sobrescriba ningún archivo existente, la>|
sintaxis le permite pasar por esta limitación:El archivo se sobrescribe cada vez, bueno ahora:
Pase con
>|
:Desarmar esta opción y / o preguntar si ya está configurado.
4 - Último truco y más ...
Para redirigir ambos resultados de un comando dado, vemos que una sintaxis correcta podría ser:
para este caso especial , hay una sintaxis de acceso directo:
&>
... o>&
Nota: si
2>&1
existe, también1>&2
es una sintaxis correcta:4b- Ahora, te dejaré pensar en:
4c- Si estás interesado en más información
Puede leer el excelente manual presionando:
en un golpetazo consola ;-)
fuente
Encontré esta brillante publicación sobre redirección: todo sobre redirecciones
Redirigir la salida estándar y el error estándar a un archivo
Este one-liner utiliza el
&>
operador para redirigir ambas secuencias de salida, stdout y stderr, desde el comando al archivo. Este es el acceso directo de Bash para redirigir rápidamente ambas transmisiones al mismo destino.Así es como se ve la tabla de descriptores de archivos después de que Bash haya redirigido ambas secuencias:
Como puede ver, tanto stdout como stderr ahora apuntan
file
. Entonces, cualquier cosa escrita en stdout y stderr se escribe enfile
.Hay varias formas de redirigir ambas transmisiones al mismo destino. Puede redirigir cada transmisión una tras otra:
Esta es una forma mucho más común de redirigir ambas secuencias a un archivo. Primero stdout se redirige al archivo, y luego stderr se duplica para que sea lo mismo que stdout. Entonces ambas corrientes terminan apuntando a
file
.Cuando Bash ve varias redirecciones, las procesa de izquierda a derecha. Veamos los pasos y veamos cómo sucede. Antes de ejecutar cualquier comando, la tabla de descriptores de archivo de Bash se ve así:
Ahora Bash procesa la primera redirección> archivo. Hemos visto esto antes y hace que stdout señale al archivo:
Next Bash ve la segunda redirección 2> & 1. No hemos visto esta redirección antes. Este duplica el descriptor de archivo 2 para que sea una copia del descriptor de archivo 1 y obtenemos:
Ambas transmisiones se han redirigido al archivo.
Sin embargo, ten cuidado aquí! Escritura
no es lo mismo que escribir:
¡El orden de redireccionamientos importa en Bash! Este comando redirige solo la salida estándar al archivo. El stderr seguirá imprimiéndose en el terminal. Para entender por qué sucede eso, repasemos los pasos nuevamente. Entonces, antes de ejecutar el comando, la tabla de descriptores de archivo se ve así:
Ahora Bash procesa las redirecciones de izquierda a derecha. Primero ve 2> & 1, por lo que duplica stderr a stdout. La tabla de descriptores de archivo se convierte en:
Ahora Bash ve la segunda redirección
>file
, y redirige stdout a archivo:¿Ves lo que pasa aquí? Stdout ahora apunta a archivo, ¡pero stderr todavía apunta a la terminal! ¡Todo lo que se escribe en stderr todavía se imprime en la pantalla! ¡Así que ten mucho cuidado con el orden de redireccionamientos!
También tenga en cuenta que en Bash, escribir
es exactamente lo mismo que:
fuente
>&
/dev/tty0
?Los números se refieren a los descriptores de archivo (fd).
stdin
stdout
stderr
2>&1
redirige fd 2 a 1.Esto funciona para cualquier número de descriptores de archivos si el programa los usa.
Puedes mirar
/usr/include/unistd.h
si los olvidas:Dicho esto, he escrito herramientas C que usan descriptores de archivo no estándar para el registro personalizado para que no lo vea a menos que lo redirija a un archivo o algo así.
fuente
Esa construcción envía el flujo de error estándar (
stderr
) a la ubicación actual de la salida estándar (stdout
); este problema de moneda parece haber sido descuidado por las otras respuestas.Puede redirigir cualquier manejador de salida a otro utilizando este método, pero se usa con mayor frecuencia para canalizar
stdout
ystderr
transmitir en un solo flujo para su procesamiento.Algunos ejemplos son:
Tenga en cuenta que el último no se dirigirá
stderr
aoutfile2
: lo redirige a lo questdout
era cuando se encontró el argumento (outfile1
) y luego lo redirigestdout
aoutfile2
.Esto permite algunos trucos bastante sofisticados.
fuente
some_program 2>&1 > /dev/null
no funciona de esta manera:some_program > /dev/null 2>&1
.2>&1
es una construcción de shell POSIX. Aquí hay un desglose, ficha por ficha:2
: Descriptor del archivo de salida " error estándar ".>&
: Duplicar un operador Descriptor de archivo de salida (una variante del operador de redirección de salida>
). Dado[x]>&[y]
, el descriptor de archivo indicado porx
se hace para ser una copia del descriptor de archivo de saliday
.1
" Salida estándar " descriptor de archivo de salida.La expresión
2>&1
copia el descriptor de archivo1
en la ubicación2
, por lo que cualquier salida escrita en2
("error estándar") en el entorno de ejecución va al mismo archivo descrito originalmente por1
("salida estándar").Explicación adicional:
Descriptor de archivo : "Un entero único no negativo por proceso utilizado para identificar un archivo abierto con el fin de acceder a él".
Salida / error estándar : consulte la siguiente nota en la sección Redirección de la documentación del shell:
fuente
2 es el error estándar de la consola.
1 es la salida estándar de la consola.
Este es el Unix estándar, y Windows también sigue al POSIX.
Por ejemplo, cuando corres
el error estándar se redirige a la salida estándar, por lo que puede ver ambas salidas juntas:
Después de la ejecución, puede ver todos los resultados, incluidos los errores, en el debug.log.
Luego, la salida estándar va a out.log y el error estándar a err.log.
Te sugiero que trates de entender esto.
fuente
perl test.pl > debug.log 2>&1
Para responder a su pregunta: toma cualquier error de salida (normalmente enviado a stderr) y lo escribe en la salida estándar (stdout).
Esto es útil con, por ejemplo, 'más' cuando necesita paginación para toda la salida. Algunos programas les gusta imprimir información de uso en stderr.
Para ayudarte a recordar
"2> & 1" simplemente señala todo lo enviado a stderr, a stdout en su lugar.
También recomiendo leer esta publicación sobre la redirección de errores donde este tema está cubierto con todo detalle.
fuente
Desde el punto de vista del programador, significa precisamente esto:
Ver la página del manual .
Entender que
2>&1
es una copia también explica por qué ...... no es lo mismo que ...
El primero enviará ambas secuencias a
file
, mientras que el segundo enviará errores astdout
, y la salida ordinaria afile
.fuente
Esto es muy útil si eres principiante, lee esto
Actualización:
en Linux o Unix System hay dos lugares a los que los programas envían resultados: Salida estándar (stdout) y Error estándar (stderr) . Puede redirigir estos resultados a cualquier archivo.
Al igual que si hace esto,
ls -a > output.txt
nada se imprimirá en la consola, toda la salida (stdout) se redirige al archivo de salida.
Y si intenta imprimir el contenido de cualquier archivo que no salga significa que la salida será un error como si imprime test.txt que no está presente en el directorio actual La
cat test.txt > error.txt
salida será
Pero el archivo error.txt estará vacío porque redirigimos el stdout a un archivo no stderr.
por lo tanto, necesitamos un descriptor de archivo (un descriptor de archivo no es más que un entero positivo que representa un archivo abierto. Se puede decir que el descriptor es la identificación única del archivo) para decirle a Shell qué tipo de salida estamos enviando al archivo. En el sistema Unix / Linux 1 es para stdout y 2 para stderr .
así que si hace esto,
ls -a 1> output.txt
significa que está enviando salida estándar (stdout) a output.txt.y si hace esto
cat test.txt 2> error.txt
significa que está enviando el Error estándar (stderr) a error.txt.&1
se utiliza para hacer referencia al valor del descriptor de archivo 1 (stdout).Ahora hasta el punto
2>&1
significa "Redirigir el stderr al mismo lugar donde estamos redirigiendo el stdout"Ahora puedes hacer esto
cat maybefile.txt > output.txt 2>&1
tanto la salida estándar (stdout) como el error estándar (stderr) serán redirigidos a output.txt.
Gracias a Ondrej K. por señalar
fuente
La gente, siempre recuerda paxdiablo pista 's acerca de la actual ubicación del objetivo de redirección ... Es es importante.
Mi nemotécnica personal para el
2>&1
operador es esta:&
el sentido'and'
o'add'
(el personaje es un amperios - y , ¿verdad?)2
(stderr) a donde1
(stdout) ya está / actualmente y agregar ambas transmisiones' .La misma mnemónica funciona también para la otra redirección utilizada con frecuencia
1>&2
:&
significadoand
oadd
... (tienes la idea sobre el signo y, ¿sí?)1
(stdout) a donde2
(stderr) ya está / actualmente y agregar ambas transmisiones' .Y recuerde siempre: debe leer las cadenas de redireccionamientos 'desde el final', de derecha a izquierda ( no de izquierda a derecha).
fuente
Árbitro:
Escriba
/^REDIRECT
para ubicar laredirection
sección y obtenga más información ...Una versión en línea está aquí: 3.6 Redirecciones
PD:
Muchas veces,
man
era la poderosa herramienta para aprender Linux.fuente
Siempre que
/foo
no exista en su sistema y/tmp
...imprimirá el contenido
/tmp
e imprimirá un mensaje de error para/foo
enviará el contenido de
/tmp
a/dev/null
e imprimir un mensaje de error de/foo
hará exactamente lo mismo (tenga en cuenta el 1 )
imprimirá el contenido
/tmp
y enviará el mensaje de error a/dev/null
enviará tanto el listado como el mensaje de error a
/dev/null
es taquigrafía
fuente
Esto es como pasar el error al stdout o al terminal.
Es decir,
cmd
no es un comando:El error se envía al archivo de esta manera:
El error estándar se envía al terminal.
fuente
0 para entrada, 1 para stdout y 2 para stderr.
Un consejo :
somecmd >1.txt 2>&1
es correcto, ¡mientras quesomecmd 2>&1 >1.txt
está totalmente equivocado sin ningún efecto!fuente
unix_commands 2>&1
Esto se utiliza para imprimir errores en el terminal.
Lo siguiente ilustra el proceso
&2
"memoria intermedia" de la dirección de memoria de error estándar , desde la cual hace2
referencia la secuencia de error estándar .&1
"buffer", desde la cual hace1
referencia el flujo de salida estándar .Por lo tanto, tome el
unix_commands
flujo de error estándar2
y redirija>
el flujo (de errores) a la dirección de memoria de salida estándar&1
, de modo que se transmitan al terminal y se impriman.fuente