2009-08-01 14 views

Respuesta

31

Técnicamente hablando, duplica o copia, stderr en stdout.

Normalmente no necesita el ejecutivo para realizar esto. Un uso más típico de exec con descriptores de archivos es indicar que desea asignar un archivo a un descriptor de archivo no utilizado, p.

exec 35< my_input

BTW No se olvide que la secuencia de la declaración cuando las tuberías en un archivo es importante, por lo

ls > mydirlist 2>&1 

funcionará, ya que dirige stdout y stderr a la mydirlist archivo, mientras que el comando

ls 2>&1 > mydirlist 

dirige solamente la salida estándar, y no stderr, para presentar mydirlist, porque stderr se hizo una copia de la salida estándar antes stdou t fue redirigido a mydirlist.

Edit: Es la forma en que el shell trabaja escaneando de izquierda a derecha. Así que lea el segundo diciendo "copiar stderr en stdout" antes de que diga "enviar stdout a mydirlist". Luego lea el primero como diciendo "envíe la salida estándar al archivo mydirlist" antes de que diga "stderr duplicado en esa salida estándar que configuré". Lo sé. ¡No es totalmente intuitivo!

+0

Lo siento, no entiendo esto. Así que dirigir stderr a stdout y luego dirigir stdout a un archivo no funciona, ¿pero dirigir stdout a un archivo y luego dirigir stderr a stdout funciona? Parece que debería ser lo contrario. –

+1

@bjarkef, ver la edición anterior. –

+0

Muy contra intuitivo de hecho. He estado tratando de hacer exactamente eso porque no sé cuántas veces y me he preguntado por qué nunca funciona. Gracias un montón. –

10

Ata error estándar a la salida estándar

la 2 es stderr y stdout es 1. Cuando ejecutas un programa, obtienes la salida normal en stdout, pero cualquier error o advertencia suele ir a stderr. Si desea canalizar toda la salida a un archivo, por ejemplo, es útil combinar primero stderr con stdout con 2>&1.

+1

ejecutivo de la llamada del hombre sh' sin orden no es necesariamente una característica oculta (su bas en el documento), pero nuevo para mí nontheless. Cosa graciosa ... –

+0

No es 'stderr a stdout'. Se podría decir que 'une stderr a stdout' o 'asocia stderr y stdout'. Los datos se canalizan, los descriptores de archivos no. –

+0

Gracias William, lo he cambiado a 'lazos' –

2

Como dijo @cma, pone stderr en stdout. La razón por la que puede querer este comportamiento es usar grep o cualquier otra utilidad para capturar resultados que solo aparecen en stderr. O quizás desee guardar todos los resultados, incluido stderr, en un archivo para su posterior procesamiento.

22

Uno de los mejores artículos que he visto en lo que "2> & 1" hace es Bash One-Liners Explained, Part III: All about redirections.

Pero lo que las respuestas actuales sobre esta pregunta no proporcionan es por qué querría hacer esto después de un simple "ejecutivo". Como la página bash man para el comando exec explica: "Si no se especifica el comando, cualquier redirección tendrá efecto en el shell actual".

me escribió un script sencillo llamado out-and-err.py que escribe una línea de salida a la salida estándar, y otra línea a stderr:

#!/usr/bin/python 
import sys 
sys.stdout.write('this is stdout.\n') 
sys.stderr.write('this is stderr.\n') 

Y entonces envuelto que en un script de shell llamó -y-err.SH con un "exec 2> & 1":

#!/bin/bash 
exec 2>&1 
./out-and-err 

Si me quedo sólo el script en Python, stdout y stderr son independientes:

$ ./out-and-err.pl 1> out 2> err 
$ cat out 
this is stdout. 
$ cat err 
the is stderr. 

Pero si corro el script de shell, se puede ver que el ejecutivo se encarga de todo lo que después de stderr:

$ ./out-and-err.sh 1> out 2> err 
$ cat out 
this is stdout. 
this is stderr. 
$ cat err 
$ 

Si su script envoltorio hace mucho más que simplemente el comando de un pitón, y que necesita toda la potencia combinada en la salida estándar, haciendo el "ejecutivo 2> & 1" hará que sea más fácil para usted.

+1

respuesta impresionante, los otros no pudieron explicar que la redirección es válida en todo el shell (o script)! y el ejemplo es clarificador. – caesarsol

0

Una aplicación bastante útil de exec 2>&1 que he encontrado es cuando desea unir stderr y stdout para varios comandos separados por punto y coma. Mi ejemplo particular ocurrió cuando yo estaba enviando más de un comando a popen en PHP y yo quería ver los errores intercalan como se podría ver si ha escrito los comandos en el intérprete de comandos:

$ echo hi ; yikes ; echo there 
hi 
-bash: yikes: command not found 
there 
$ 

Lo siguiente no fusionarse stderr y stdout a excepción de la última echo (que no tiene sentido porque el yikes provoca el error):

echo hi ; yikes ; echo there 2>&1 

yo puede conseguir la salida resultante de la fusión del "camino difícil" de la siguiente manera:

echo hi 2>&1; yikes 2>&1; echo there 2>&1 

Se ve mucho más limpio y menos propenso a errores si utiliza exec:

exec 2>&1 ; echo hi; echo yikes; echo there 

Se obtiene la salida stdout y stderr muy bien intercalados exactamente como se podría ver en el terminal si se ejecutara los tres comandos separados por punto y coma

Cuestiones relacionadas