Diferencia entre 2> & -, 2> / dev / null, | &, &> / dev / null y> / dev / null 2> & 1

192

Solo buscando la diferencia entre

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

y su facilidad de transporte y non-Bourne shellscomo tcsh, mksh, etc.

Det
fuente
2
Tenga en cuenta que, si bien mksh admite la &>compatibilidad con bash de GNU, se recomienda encarecidamente no usar esto, ya que analizarlo puede romper la semántica de los scripts POSIX existentes, y mksh ya lo desactiva en modo POSIX.
mirabilos
También he visto ^ /dev/nullqué hace eso.
balupton

Respuestas:

241

Para el fondo:

  • un número 1 = salida estándar (es decir, STDOUT)
  • un número 2 = error estándar (es decir, STDERR)
  • si no se da un número explícitamente, el shell asume el número 1 (bash)

Primero abordemos la función de estos. Para referencia, consulte la Guía avanzada de secuencias de comandos Bash .

Las funciones

2>&-

La forma general de este es M>&-, donde "M" es un número de descriptor de archivo. Esto cerrará la salida para cualquier descriptor de archivo al que se haga referencia, es decir, "M" .

2>/dev/null

La forma general de este es M>/dev/null, donde "M" es un número de descriptor de archivo. Esto redirigirá el descriptor de archivo, "M" , a /dev/null.

2>&1

La forma general de este es M>&N, donde "M" y "N" son números de descriptor de archivo. Combina la salida de los descriptores de archivo "M" y "N" en una sola secuencia.

|&

Esto es solo una abreviatura de 2>&1 |. Fue agregado en Bash 4.

&>/dev/null

Esto es solo una abreviatura de >/dev/null 2>&1. Redirige el descriptor de archivo 2 (STDERR) y el descriptor 1 (STDOUT) a /dev/null.

>/dev/null

Esto es solo una abreviatura de 1>/dev/null. Redirige el descriptor de archivo 1 (STDOUT) a /dev/null.

Portabilidad a no bash, tcsh, mksh, etc.

No he tratado mucho con otros proyectiles fuera de cshy tcsh. Mi experiencia con esos 2 en comparación con los operadores de redirección de bash es que bash es superior en ese sentido. Consulte la página de manual de tcsh para obtener más detalles.

De los comandos que preguntó sobre ninguno, csh / tcsh admite directamente. Tendría que usar diferentes sintaxis para construir funciones similares.

slm
fuente
Tenemos un ganador. ¿Pero entonces no hay diferencia de rendimiento o algo así con 2>&-vs 2>/dev/null(aparte de eso, algunos programas escritos "mal" no se entienden 2>&-correctamente)?
Det.
3
No debería haber diferencia de rendimiento.
slm
55
&>estuvo bashdesde el principio (y rompe la compatibilidad de Bourne y POSIX ya que significa algo diferente allí, aunque es poco probable que se vea afectado). >&y |&provienen de (t)csh(y es su única forma de redirigir stderr). Estuvieron zshdesde el principio y solo se han agregado recientemente bash. Ver también rcpara operadores mejor diseñados.
Stéphane Chazelas
1
Actualización: sobre el problema de rendimiento, eso también se confirma aquí: unix.stackexchange.com/questions/163955/…
Det
1
Hola @slm, gracias por el contacto. Me alegra que mi repositorio no haya cambiado (+2-2=0). Ahora, en la parte de edición, no edito mucho, pero en este caso lo haría, porque aclara que los datos después de la operación estarían en N. Leí su respuesta, y está muy bien en todos los aspectos. Solo esta pequeña ambigüedad me hizo pensar, por eso la edición. Pero está bien, siéntase libre de volver a agregarlo o rechazarlo, como lo hará. Espero poder explicar el punto. Sigan con el buen trabajo.
Dr. Beco
11

Esto es para redirigir el STDERR y STDOUT:

  • 2>/dev/null

    Redirigir STDERR a / dev / null (evitar que aparezca en la consola)

  • |&

    Redireccionar STDERR y STDOUT a STDIN del comando canalizado (cmd1 | y cmd2)

  • &>/dev/null

    Redireccionar STDERR y STDOUT a / dev / null (no aparece nada en la consola)

  • >/dev/null

    Redireccionar STDOUT a / dev / null (solo se muestra STDERR en la consola)

  • 2>&-

    Es para cerrar un descriptor de archivo usado con redirección

Todos estos son métodos de redireccionamiento estándar para los shells Bourne.

BriGuy
fuente
44
|&y no&>/dev/null son portátiles
Chris Down
4

Considere esto como un apéndice a la respuesta seleccionada. Es posible que desee saber qué formularios son POSIX y cuáles no.

Están involucrados dos formularios POSIX:

2.7.2 Salida de redireccionamiento

Los dos formatos generales para redirigir la salida son:

[n]> palabra

[n]> | palabra

donde el n opcional representa el número de descriptor de archivo. Si se omite el número, la redirección se referirá a la salida estándar (descriptor de archivo 1).

La redirección de salida utilizando el formato '>' fallará si se establece la opción noclobber (consulte la descripción del conjunto -C) y el archivo nombrado por la expansión de la palabra existe y es un archivo normal. De lo contrario, la redirección con '>' o "> |" los formatos deberán crear y abrir el archivo cuyo nombre resulta de la expansión de la palabra para su salida en el descriptor de archivo designado, o salida estándar si no se especifica ninguno. Si el archivo no existe, se creará; de lo contrario, se truncará para que sea un archivo vacío después de abrirse.

-

2.7.6 Duplicar un descriptor de archivo de salida

El operador de redireccionamiento:

[n]> y palabra

duplicará un descriptor de archivo de salida de otro, o cerrará uno. Si la palabra se evalúa con uno o más dígitos, el descriptor de archivo denotado por n, o la salida estándar si no se especifica n, se hará una copia del descriptor de archivo denotado por palabra; si los dígitos en la palabra no representan un descriptor de archivo ya abierto para la salida, se producirá un error de redireccionamiento; ver Consecuencias de los errores de Shell. Si la palabra se evalúa como '-', se cierra el descriptor de archivo n, o la salida estándar si no se especifica n. Los intentos de cerrar un descriptor de archivo que no esté abierto no constituirán un error. Si la palabra se evalúa como algo diferente, el comportamiento no se especifica.

Por lo tanto:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

La última línea no está en la pregunta original, pero funciona sin quejas en bash. (También funciona con / dev / tty sustituido por / dev / null).

Craig Hicks
fuente
1
Siempre quiero saber más
Det