2012-02-17 10 views
10

2>&1 redirigir en Bourne shell toma la salida enviada a un descriptor de archivo 2 (por defecto, error estándar) y lo envía en su lugar al descriptor de archivo 1 (por defecto una salida estándar).¿Qué hace "2 <& 1" redirigir en Bourne shell?

Pero, ¿qué hace el redireccionamiento 2<&1?

¿Envía stderr a stdin?

Mi teoría era que estaba enviando a la entrada estándar salida estándar de errores (por ejemplo, mismo que 1>&2) pero de forma experimental, que no es el caso:

$ perl -e 'print "OUT\n"; print STDERR "ERR\n"; \ 
    while (<>) { print "IN WAS $_\n";}'   \ 
    > out3 2<&1 
df 
$ cat out3 
ERR 
OUT 
IN WAS df 

Tenga en cuenta que la salida estándar y el error estándar ambos fueron a presentar OUT3 en la salida estándar fue redirigido

+0

Como nota - esto era una (supuesta) de errores de un co trabajador ingresó cuando usó erróneamente '<' en lugar de '>'. Solo estoy tratando de entender exactamente lo que está haciendo Shell con eso. Hasta ahora, PARECE como si fuera lo mismo que '2> & 1' – DVK

+0

' bash --version'? –

+0

@ user112358132134 - 'GNU bash, versión 2.03.0 (1) -release (sparc-sun-solaris2.5.1)' – DVK

Respuesta

6

El operador <& duplica una “entrada "Descriptor de archivo. De acuerdo con IEEE Std 1003.1-2001 (también conocido como Single Unix Specification v3, el sucesor de POSIX), se supone que es un error decir 2<&1 si 1 no es un descriptor de archivo abierto para la entrada. Sin embargo, parece que bash es flojo y no le importa si el descriptor de archivo está abierto para la entrada o salida.

Así pues, tanto 2<&1 y 2>&1 Basta con realizar la llamada al sistema dup2(1, 2), que descriptor de archivo de copias del 1 al descriptor de archivo 2.

Usted puede comprobar mediante la ejecución de un comando como este, ya que se realizan cambios de dirección de izquierda a derecha:

sleep 99999 1>/dev/null 2<&1 

Luego, en otra ventana, ejecute lsof en el proceso de sleep. Verá que ambos descriptores de archivos 1 y 2 apuntan a /dev/null. Ejemplo (en mi Mac):

:; ps axww | grep sleep 
8871 s001 R+  0:00.01 grep sleep 
8869 s003 S+  0:00.01 sleep 99999 
:; lsof -p 8869 | tail -2 
sleep 8869 mayoff 1w CHR 3,2  0t0  316 /dev/null 
sleep 8869 mayoff 2w CHR 3,2  0t0  316 /dev/null 
+0

Entonces, usted 'diciendo' 2 <& 1 'es ** efectivamente ** equivalente a '2> & 1' en Bash (especialmente para el comando que no lee de STDIN), incluso si teóricamente no debería ser así, ¿correcto? – DVK

+0

No del todo. '2 <& 1' es equivalente a' 1> & 2'. –

+0

lo siento, parece que no concuerda con mi prueba (vea la pregunta). ERR se redirigió a OUT, al parecer, no al revés – DVK

0

De man bash bajo REDIRECCIONAMIENTO:

Duplicating File Descriptors 
     The redirection operator 

       [n]<&word 

     is used to duplicate input file descriptors. If word 
     expands to one or more digits, the file descriptor 
     denoted by n is made to be a copy of that file descrip‐ 
     tor. If the digits in word do not specify a file 
     descriptor open for input, a redirection error occurs. 
     If word evaluates to -, file descriptor n is closed. If 
     n is not specified, the standard input (file descriptor 
     0) is used. 

Así, en el caso de , parece que 2 (stderr) está hecho para ser una copia de 1 (stdout). Lo he probado al revés 1<&2 hace que stdout sea una copia de stderr.

Así que en un programa de prueba:

#!/bin/bash 
echo hello 1<&2 

cuando se ejecuta en la línea de comandos, hola se da salida a stderr no stdout

$ ./test > /dev/null 
hello 
$ ./test > /dev/null 2>&1 
$ 
+0

Su prueba probó el redireccionamiento incorrecto. Sé lo que 2> & 1 hace - por favor lea cuidadosamente la pregunta – DVK

+0

La prueba en mi respuesta fue para 1 & 1 solo se aseguraba de que 1 & amp; 2 duplicara stderr – vmpstr

4

Mirando el código de programa de análisis de la fuente de Bash, parece que 2>&1 es tratada de la misma manera que 2<&1.

parse.Y

| NUMBER LESS_AND NUMBER 
     { 
      redir.dest = $3; 
      $$ = make_redirection ($1, r_duplicating_input, redir); 
     } 
... 
| NUMBER GREATER_AND NUMBER 
     { 
      redir.dest = $3; 
      $$ = make_redirection ($1, r_duplicating_output, redir); 
     } 

Mirando a través de la fuente de redirección redir.c, las constantes r_duplicating_input y r_duplicating_output parece ser tratado de la misma manera. Lo mismo que en la función make_redirection en make_cmd.c.

de pruebas con un sencillo programa que imprime "yay" a la salida estándar y "más aún" en stderr, puedo confirmar los resultados de la prueba:

$ ./a.out > out 2>&1 
$ cat out 
nay 
yay 
$ ./a.out > out 2<&1 
$ cat out 
nay 
yay 
$ ./a.out > out 1>&2 
yay 
nay 
$ cat out 
$ ./a.out > out 1<&2 
yay 
nay 
$ cat out 
$ 
+0

+1, respuesta excelente también – DVK

Cuestiones relacionadas