1734 votos

En el shell, lo que es " 2>&1 "?

En un shell de unix, si quiero combinar stderr y stdout en el stdout del arroyo para su posterior manipulación, puedo anexar la siguiente en el final de mi comando:

2>&1

Así que, si quiero utilizar "la cabeza" sobre la salida de g++, puedo hacer algo como esto:

g++ lots_of_errors 2>&1 | head

por lo que puedo ver solo el primer par de errores.

Siempre tengo problemas para recordar esto, y yo constantemente tengo que ir a mirar hacia arriba, y es principalmente porque no entiendo la sintaxis de este truco particular. Alguien puede romper este y explicar el carácter por carácter, lo que "2>&1" significa?

1942voto

Ayman Hourieh Puntos 39435

1 es stdout. 2 es stderr.

Aquí es una forma de recordar este constructo (aunque no es del todo exacto): en primer lugar, 2>1 puede parecer una buena manera de redirigir stderr a stdout. Sin embargo, en realidad, será interpretado como "redirigir stderr a un archivo denominado 1". & indica que lo que sigue es un descriptor de fichero y no un nombre de archivo. Para la construcción se convierte en: 2>&1.

481voto

dbr Puntos 66401
echo test > afile.txt

..redirige stdout afile.txt. Esto es lo mismo que hacer..

echo test 1> afile.txt

Para redirigir stderr, que hacer..

echo test 2> afile.txt

>& es la sintaxis para redirigir un flujo a otro descriptor de archivo - 0 es stdin. 1 es stdout. 2 es stderr.

Usted puede redirigir stdout a stderr haciendo..

echo test 1>&2 # or echo test >&2

..o viceversa:

echo test 2>&1

Así que, en breve.. 2> redirige stderr a un (no especificado) de archivo, anexando &1 redirige stderr a stdout

256voto

F. Hauri Puntos 5893

Algunos trucos acerca de la redirección de

Algunos sintaxis de particularidad acerca de esto puede tener importantes comportamientos. Hay algunas pequeñas muestras sobre las redirecciones, STDERR, STDOUT y los argumentos de pedido.

1 - Overwritting o anexar?

Symbole > la media de la redirección.

  • > significa enviar a como todo el archivo completo, sobrescribiendo destino si existe (ver noclobber característica de bash en el#3, más adelante).
  • >> significa enviar, además gustaría añadir a destino si existe.

En cualquier caso, el archivo puede ser creado si no existe.

2 - La línea de comandos de shell es de orden cargo!!

Para probar esto, necesitamos un simple comando que va a enviar algo sobre ambas salidas:

$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

(Esperando que usted no tiene un directorio llamado /tnt, por supuesto ;). Así, la tenemos!!

Así que vamos a ver:

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1

$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory

La última línea de comandos dump STDERR a la consola, parece no ser el comportamiento esperado... Pero...

Si desea hacer algún post filtrado sobre una salida de la señal, el otro, o ambos:

$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'

$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->

Observe que la última línea de comandos en este párrafo es exactamente el mismo como en los anteriores paraghaph, donde escribí parecen no ser el comportamiento esperado (por lo tanto, este podría ser un comportamiento esperado).

Bueno, hay un poco de trucos sobre redirecciones, para haciendo diferentes en ambos salidas de:

$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2  2>&1  | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan  7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory

Nota: &9 descriptor iba a producirse espontáneamente debido ) 9>&2.

Y, finalmente, para una cascada formato de salida:

$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
     1      O: drwxrwxrwt 118 root root 196608 Jan  7 12:29 /tmp
     2      E: ls: cannot access /tnt: No such file or directory

Donde STDOUT ir a través de un filtro específico, STDERR a otro y, finalmente, ambas salidas combinadas ir a través de un tercer comando de filtro.

3 - Una palabra acerca de noclobber opción y >| de sintaxis

Que trata de overwritting:

Mientras set -o noclobber instruir bash para no sobrescribir cualquier archivo existente, la >| de sintaxis permiten pasar a través de esta limitación:

$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:15 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:19 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:21 CET 2013

Archivo overwritted cada momento, así ahora:

$ set -o noclobber

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

Pasar a través de la con >|:

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:19:01 CET 2013

La desconexión de esta opción y/o preguntando si ya establecidos.

$ set -o | grep noclobber
noclobber           on

$ set +o noclobber

$ set -o | grep noclobber
noclobber           off

$ date > $testfile ; cat $testfile
Mon Jan  7 13:24:27 CET 2013

$ rm $testfile

4 - la Última baza y más...

Para redireccionar , tanto de salida de un comando determinado, vemos que un derecho de sintaxis pueden ser:

$ ls -ld /tmp /tnt >/dev/null 2>&1

para este especial caso, hay un acceso directo sintaxis: &>

$ ls -ld /tmp /tnt &>/dev/null 

Nota: si 2>&1 existir, 1>&2 de una correcta syntaxe:

$ ls -ld /tmp /tnt 2>/dev/null 1>&2

4b - Ahora, voy a dejar que usted piensa acerca de:

$ ls -ld /tmp /tnt 2>&1 1>&2  | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

$ ls -ld /tmp /tnt 1>&2 2>&1  | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

4c - Si usted está interesado en obtener más informaciones

se podía Leer El Manual por golpear a:

man -Len -Pless\ +/^REDIRECTION bash

en un consola ;-)

104voto

Bill Karwin Puntos 204877
  • 2 es el valor predeterminado de descriptor de archivo para stderr.
  • 1 es el valor predeterminado de descriptor de archivo para la salida estándar (stdout).
  • >& es cáscara de sintaxis para "doblar la anterior (la primera) descriptor de archivo en la próxima (segundo) descriptor de archivo."

49voto

paxdiablo Puntos 341644

Que construir envía el flujo de error estándar (stderr) a la actual ubicación de la salida estándar (stdout) - esta moneda problema parece haber sido abandonados por el otro las respuestas.

Usted puede redireccionar la salida de manejar a otro utilizando este método, pero es más a menudo utilizado para canal stdout y stderr arroyos en un único flujo para el procesamiento.

Algunos ejemplos son:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Tenga en cuenta que la última voluntad de no dirigir stderr a outfile2 - redirige a lo stdout fue cuando el argumento fue encontrado (outfile1) y , a continuación, redirecciones stdout a outfile2.

Esto permite que algunas bastante sofisticadas artimañas.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X