Orden de redireccionamientos

29

No entiendo cómo la computadora lee este comando.

cat file1 file2 1> file.txt 2>&1

Si entiendo, 2>&1simplemente redirija el Error estándar a la Salida estándar.

Según esa lógica, el comando me dice lo siguiente:

  1. concatenar archivos file1y file2.

  2. enviar stdoutdesde esta operación a file.txt.

  3. enviar stderra stdout.

  4. ¿fin?

No estoy seguro de lo que está haciendo la computadora. Según mi lógica, el comando debería ser

cat file1 file2 2>&1 > file.txt

Pero esto no es correcto.

iDontKnowBetter
fuente

Respuestas:

46

Me resulta más fácil pensar en usar tareas.

  • > es como =
  • & es como $

Empiezas con

1 = /dev/tty
2 = /dev/tty

entonces su primer ejemplo, 1> file.txt 2>&1, hace

1 = file.txt
2 = $1           # and currently $1 = file.txt

dejándote con

1 = file.txt
2 = file.txt

Si lo hiciste de la otra manera, nuevamente comienzas con

1 = /dev/tty
2 = /dev/tty

entonces 2>&1 > file.txthace

2 = $1           # and currently $1 = /dev/tty
1 = file.txt

entonces el resultado final es

1 = file.txt
2 = /dev/tty

y solo has redirigido stdout, no stderr.

Mikel
fuente
entiendo la analogía, pero es confusa: ¿qué significa $?
Eliran Malka
En una tarea como var=$othervar, $introduce el nombre de la variable en el lado derecho. En una redirección como 2>&1, &introduce el número de descriptor de archivo en el lado derecho. Estoy diciendo que puedes pensar que "el archivo 2 es igual al archivo 1". (Pero hay dos tipos de iguales: <significa "para leer" y >significa "para escribir".)
Mikel
12

El orden de redireccionamiento es importante, y deben leerse de izquierda a derecha .

Por ejemplo: command 2>&1 >somefilesignifica:

  1. Redireccionar stderr(es decir 2) al destino actual de stdout(en este punto, el terminal).
  2. Luego cambia stdoutpara ir a somefile.

Entonces, en este caso, stderrva a la terminal y stdoutva a un archivo, que no es lo que probablemente desee.

Por otro lado, command >somefile 2>&1significa:

  1. Redirigir stdoutasomefile
  2. Luego redirija stderral mismo destino que stdout( somefile).

En este último caso, tanto stderry stdoutde ir a somefile, que es probablemente lo que quiere.

Amelio Vazquez-Reina
fuente
4
cat file1 file2 1> file.txt 2>&1

>& En realidad significa duplicado, utiliza la llamada al sistema dup para asignar un nuevo descriptor de archivo a un archivo ya abierto.

Entonces, (bash en realidad) primero debe abrir el nuevo stdout antes, diciendo "y redirigir stderr a cualquier stdout que esté configurado actualmente".

X Tian
fuente
esto es asombroso! Me he estado preguntando sobre eso &. ¿podría incluir algunas referencias a esa sintaxis o, mejor aún, algunos buenos recursos en el sistema dup antes mencionado?
Eliran Malka
1
'man dup' documenta la llamada al sistema.
X Tian
tiene sentido :) gracias
Eliran Malka