GNU/Linux >> Tutoriales Linux >  >> Linux

¿Importancia de los símbolos de flechas al duplicar/cerrar descriptores de archivos en Bash?

Estoy leyendo un libro sobre la línea de comandos de Linux donde el autor no parece seguir las convenciones del manual de bash con respecto a los símbolos de flechas utilizados en las operaciones de redirección. Es decir, siempre usa la flecha izquierda < en duplicar y cerrar descriptores de archivos sin importar si los descriptores son de entrada o de salida.

Aquí hay un ejemplo:

exec 3<&0 4<&1 #shouldn't be 4>&1 ?
#...
exec 3<&- 4<&- #shouldn't be 4>&- ?

La página de manual de Bash es vaga en este punto, según ella, los descriptores de duplicación/cierre y movimiento de archivos tienen las siguientes sintaxis:

#Duplicating and closing (in case word expands to -):
[n]<&word 
[n]>&word

#Moving:
[n]<&digit-
[n]>&digit-

Se describe que tienen un comportamiento diferente solo si no proporcionamos explícitamente el n . Pero cuando lo hacemos, ¿significa que podemos usar estas formas indistintamente?

Respuesta aceptada:

No importa porque tanto 4>&1 y 4<&1 haz lo mismo:dup2(1, 4) que es la llamada al sistema para duplicar un fd en otro. El fd duplicado hereda automáticamente la dirección de E/S del fd original. (lo mismo para 4>&- contra 4<&- que ambos se resuelven en close(4) , y 4>&1- que es el dup2(1, 4) seguido de close(1) ).

Sin embargo, el 4<&1 la sintaxis es confusa a menos que, por algún motivo, el fd 1 esté explícitamente abierto para lectura (lo que sería aún más confuso), por lo que, en mi opinión, debería evitarse.

El fd duplicado comparte la misma descripción del archivo abierto lo que significa que comparten el mismo desplazamiento en el archivo (para aquellos tipos de archivo donde tiene sentido) y las mismas banderas asociadas (redireccionamiento de E/S/modo de apertura, O_APPEND, etc.).

En Linux, hay otra forma de duplicar un fd (que no es realmente una duplicación) y cree una nueva descripción de archivo abierto para el mismo recurso pero posiblemente con banderas diferentes.

exec 3> /dev/fd/4

Mientras que en Solaris y probablemente en la mayoría de los otros Unices, eso es más o menos equivalente a dup2(4, 3) , en Linux, que abre el mismo recurso que apunta el fd 4 from scratch.

Esa es una diferencia importante porque, por ejemplo, para un archivo regular, el desplazamiento de fd 3 será 0 (el comienzo del archivo) y el archivo se truncará (por lo que, por ejemplo, en Linux necesita escribir tee -a /dev/stderr en lugar de tee /dev/stderr ).

Relacionado:¿Cómo decirle a Firefox que use otro dispositivo ALSA?

Y el modo de E/S puede ser diferente.

Curiosamente, si fd 4 apuntaba al extremo de lectura de una tubería, entonces fd 3 ahora apunta al extremo de escritura (/dev/fd/3 se comporta como una tubería con nombre ):

$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b

$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b

Linux
  1. Más trucos estúpidos de Bash:variables, búsqueda, descriptores de archivos y operaciones remotas

  2. ¿Se puede conectar un script Bash a un archivo?

  3. El Bash'?

  4. ¿Realizando operaciones de escritura atómica en un archivo en Bash?

  5. Bash:¿No existe tal archivo o directorio?

Bash:Agregar al archivo

Cómo redirigir stderr a stdout en Bash

Sustitución de cadena en Bash

35 ejemplos de secuencias de comandos Bash

Bash Scripting - Declaraciones condicionales

Script Bash (III)