Yo se que
program > /dev/null 2>&1
hace. Redirige la salida a /dev/null
y 2>&1
significa redirigir la salida de error al mismo lugar donde se envía la salida.
Mi problema es que siempre tengo que buscarlo en Google porque nunca lo recuerdo.
Entonces, intento &2>1
, 1>2&
, 1>&2
... Intento todas las combinaciones hasta que lo busco en Google ...
¿Cuál es el truco para recordarlo fácilmente?
La salida es mejor que el error, por lo que es lo primero (1 frente a 2).
>
es la abreviatura de 'va a'. A la izquierda está lo que quiero enviar y a la derecha es donde quiero enviarlo. Dado que 'donde' es (casi) siempre un archivo, algo como
program > /dev/null 2>1
redirigiría a un archivo llamado 1. Por lo tanto, el signo comercial (&)
modifica el archivo a descriptor de archivo.
Desafortunadamente, no he encontrado ni desarrollado mi propio mnemónico, pero cuando estaba aprendiendo * nix, encontré esta forma lógica de trabajar bien. Después de algunos ensayos, se convierte en una segunda naturaleza.
Un truco es recordar que 1 = salida estándar, 2 = error estándar. Entonces:
2>&1
= el flujo de error estándar entra en el flujo de salida estándar.1>&2
= viceversa.
Si alguna vez ha programado en un lenguaje similar a C, es fácil recordar el y comercial (&
). Elijo pensar en ello como una referencia a la "dirección de" descriptor de archivo existente, para que no cambie el archivo en sí ni cree uno nuevo.
Viendo el &
como un nudo podría ayudar: piense en lo que quiere hacer tomando el resultado de 2, así que 2>
, y atándolo junto con 1, así que 2>&1
Consideremos estas tres opciones:
program 2>1
program 2>1&
program 2>&1
El primero envía stderr a un archivo con el nombre "1": después de todo, bash espera redirigirlo a un archivo.
El segundo también redirige al mismo archivo pero ejecuta program
en segundo plano: eso es lo que un &
se supone que significa.
Eso deja la tercera posibilidad como la única que tiene sentido en el universo de bash para redirigir a un identificador de archivo.
¿Cómo recordar cuál es cuál entre 0, 1, 2? Piense en ejecutar una computadora desde la consola. Primero, debe escribir algo (0 = stdin). Luego, verá la salida (1 = stdout). Por último, y solo si algo sale mal, verá stderr (2).
De hecho, depende de qué Shell esté usando. Bash suele ser muy indulgente y puedes hacer lo siguiente:
program &> file
Dibuja en tu fondo de pantalla.
Ahora, en serio, esto y otras cosas básicas que seguía olvidando, así que agregué un menú de consejos rápidos a una aplicación que desarrollé y que uso a diario. Es posible que desee probarlo o usar algo como gnote para tomar nota.
En lo que respecta al bash Shell, creo que la mejor manera de recordarlo es entendiendo lo que está sucediendo.
Si todo lo que quiere hacer es recordar cómo hacer que el comando sea correcto, puede intentar
program > /results 2> /results
Eso es agradable y obvio y fácil de recordar. es decir.
1
STDOUT va a /results
2
STDERR también va directamente a /results
el problema es que esto no funciona como cabría esperar. considera lo siguiente:
expediente: /tmp/poem.txt
the quick brown fox jumped over the lazy dog
y ejecuta el comando
grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results
luego
$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
lazy dog
¿Que pasó aquí?
Tengo entendido que bash configura la redirección que apunta al STDERR directamente al archivo /tmp/results
y debido a la naturaleza de >
que hace 2 cosas
>>
hace.Entonces, en este caso STDERR, se inserta directamente al principio de /tmp/results
anulando la salida de STDOUT.
Nota: si usó >>
para agregar probablemente podría salirse con la suya con esta sintaxis.
Sin embargo, para solucionar el problema, necesita - no redirigir STDERR - al archivo directamente, sino más bien fusionar la salida de STDERR en STDOUT Stream, para que no se produzca una colisión.
Usando el operador 2>&1
operador logra esto
grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1
Los &
permite que bash se distinga de un archivo llamado 1
y el 1
descriptor de archivo.
Para mí la declaración 2>&1
en sí mismo explica exactamente lo que está sucediendo - STDERR está siendo redirigido a STDOUT mismo - y solo termina en /tmp/results
porque ahí es donde se apunta STDOUT (casi como un efecto secundario).
A diferencia de lo que afirman muchas guías, que es que 2>&1
envía STDERR a donde se apunta STDOUT. Si eso fuera cierto, aún tendría el problema de sobrescritura.
Para obtener más información, consulte - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection
Leer 2>&1
como redireccionar stderr (2), a donde stdout (1) es actualmente yendo.
A medida que leemos (y se procesa) de izquierda a derecha. La lectura correcta de >file 2>&1
es stdout directo al archivo, luego stderr directo al mismo lugar al que va ahora stdout.