GNU/Linux >> Tutoriales Linux >  >> Linux

¿Descriptores de archivos y secuencias de comandos de Shell?

Me está costando mucho entender cómo se usan los descriptores de archivos en los scripts de shell.

Conozco los conceptos básicos como

exec 5 > /tmp/foo

Entonces, fd 5 se adjunta a foo para escribir.

exec 6 < /tmp/bar

… para leer.

exec 5>&-

… cerrar fd.

Ahora, ¿qué hace esto?

#!/bin/bash

exec 5 > /tmp/foo 
exec 6 < /tmp/bar 

cat <&6 | while read a
do
     echo $a >&5
done

Según tengo entendido &5 cierra el fd, entonces, ¿cómo se sigue redirigiendo la salida con éxito después de cada llamada?

Esta es una copia de pasta de:Aquí

Afirma usar esto sobre un simple archivo echo $a > file lo haría mucho más rápido, sin embargo, no entiendo. Apreciaría cualquier enlace a un tutorial decente. Parece que los poderes de Google me están fallando.

Respuesta aceptada:

Primero, tenga en cuenta que la sintaxis para cerrar es 5>&- o 6<&- , dependiendo de si el descriptor de archivo se lee para escribir o para leer. Parece que hay un error tipográfico o de formato en esa publicación de blog.

Aquí está el guión comentado.

exec 5>/tmp/foo       # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar       # open /tmp/bar for reading, on fd 6
cat <&6 |             # call cat, with its standard input connected to
                      # what is currently fd 6, i.e., /tmp/bar
while read a; do      # 
  echo $a >&5         # write to fd 5, i.e., /tmp/foo
done                  # 

No hay cierre aquí. Debido a que todas las entradas y salidas van al mismo lugar en este ejemplo simple, no es necesario el uso de descriptores de archivos adicionales. Podrías escribir

cat </tmp/bar |
while read a; do
  echo $a
done >/tmp/foo

El uso de descriptores de archivo explícitos se vuelve útil cuando desea escribir en varios archivos a la vez. Por ejemplo, considere una secuencia de comandos que envía datos a un archivo de salida de datos y registra datos en un archivo de registro y posiblemente también mensajes de error. Eso significa tres canales de salida:uno para datos, uno para registros y otro para errores. Dado que solo hay dos descriptores estándar para la salida, se necesita un tercero. Puede llamar a exec para abrir los archivos de salida:

exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&-  # close the data output file
echo "output file closed" >&3

El comentario sobre la eficiencia aparece cuando tiene una redirección en un bucle, como este (suponga que el archivo está vacío para empezar):

while …; do echo $a >>/tmp/bar; done

En cada iteración, el programa abre /tmp/bar , busca el final del archivo, agrega algunos datos y cierra el archivo. Es más eficiente abrir el archivo de una vez por todas:

while …; do echo $a; done >/tmp/bar

Cuando hay varias redirecciones en diferentes momentos, llamar a exec para realizar redirecciones en lugar de envolver un bloque en una redirección se vuelve útil.

exec >/tmp/bar
while …; do echo $a; done

Encontrará varios otros ejemplos de redirección navegando por io-redirection etiqueta en este sitio.

Relacionado:Personalización de bash shell:¿Negrita/colorear el comando?
Linux
  1. ¿Cómo crear un archivo temporal en Shell Script?

  2. ¿Mecanismo de bloques de declaraciones en secuencias de comandos de Shell?

  3. ¿Debo usar Apt o Apt-get en secuencias de comandos de Shell?

  4. Subprocesos y descriptores de archivos

  5. Shell:escribe contenido variable en un archivo

Bash Scripting - Declaraciones condicionales

Script Bash (III)

¿Qué es Shebang en Linux Shell Scripting?

Shell Scripting Parte 4:entrada, salida y redirección

Tutorial paso a paso de secuencias de comandos de Shell

¿Qué es un archivo .sh?