Articulo de referencia

Tubería (Unix)

Una secuencia de tres procesos de programa se ejecuta en una terminal de texto. En los sistemas operativos tipo Unix , una tubería es un mecanismo de comunicación entre procesos...

Una secuencia de tres procesos de programa se ejecuta en una terminal de texto.

En los sistemas operativos tipo Unix , una tubería es un mecanismo de comunicación entre procesos mediante el paso de mensajes . Una tubería es un conjunto de procesos encadenados por sus flujos estándar , de modo que el texto de salida de cada proceso ( stdout ) se pasa directamente como entrada ( stdin ) al siguiente. El segundo proceso se inicia mientras el primero aún se está ejecutando, y ambos se ejecutan simultáneamente .

El concepto de tuberías fue impulsado por Douglas McIlroy en Bell Labs , la cuna de Unix , durante el desarrollo de este sistema operativo, dando forma a su filosofía de herramientas . Su nombre se inspira en una tubería física . Una característica clave de estas tuberías es que ocultan los detalles internos, lo que permite una mayor claridad y simplicidad en el sistema.

Las tuberías en la canalización son tuberías anónimas (a diferencia de las tuberías con nombre ), donde los datos escritos por un proceso son almacenados en búfer por el sistema operativo hasta que son leídos por el siguiente proceso, y este canal unidireccional desaparece cuando los procesos finalizan. La sintaxis estándar de la shell para tuberías anónimas consiste en enumerar varios comandos, separados por barras verticales (" pipes " en la terminología común de Unix).

Historia

El concepto de tubería fue inventado por Douglas McIlroy [ 1 ] y descrito por primera vez en las páginas man de la versión 3 de Unix . [ 2 ] [ 3 ] McIlroy observó que, con frecuencia, los intérpretes de comandos pasaban el archivo de salida de un programa como entrada a otro. Douglas McIlroy impulsó el concepto de tuberías en Bell Labs , el lugar donde se originó Unix , durante el desarrollo de este sistema operativo, dando forma a su filosofía de herramientas . [ 4 ] [ 5 ]

Sus ideas se implementaron en 1973 cuando ("en una noche febril", escribió McIlroy) Ken Thompson añadió la pipe()llamada al sistema y las tuberías al intérprete de comandos y a varias utilidades en la versión 3 de Unix. "Al día siguiente", continuó McIlroy, "se produjo una orgía inolvidable de frases ingeniosas mientras todos se unían a la emoción de la fontanería". McIlroy también le atribuye a Thompson la |notación, que simplificó enormemente la descripción de la sintaxis de las tuberías en la versión 4. [ 6 ] [ 2 ]

Aunque se desarrollaron de forma independiente, las tuberías de Unix están relacionadas con, y fueron precedidas por, los "archivos de comunicación" desarrollados por Ken Lochner [ 7 ] en la década de 1960 para el sistema de tiempo compartido de Dartmouth . [ 8 ]

Otros sistemas operativos

Esta característica de Unix fue adoptada por otros sistemas operativos, como MS-DOS y el paquete CMS Pipelines en VM/CMS y MVS , y finalmente llegó a denominarse patrón de diseño de tuberías y filtros en la ingeniería de software .

Desarrollo de conceptos adicionales

En los procesos secuenciales comunicantes (CSP) de Tony Hoare , las tuberías de McIlroy se desarrollan aún más. [ 9 ]

Implementación

Se utiliza un mecanismo de canalización para la comunicación entre procesos mediante el paso de mensajes. Una canalización es un conjunto de procesos encadenados por sus flujos estándar , de modo que el texto de salida de cada proceso ( stdout ) se pasa directamente como entrada ( stdin ) al siguiente. El segundo proceso se inicia mientras el primero aún se está ejecutando, y ambos se ejecutan concurrentemente . Su nombre se debe a la analogía con una tubería física . Una característica clave de estas canalizaciones es su "ocultación de detalles internos". [ 10 ] Esto, a su vez, permite una mayor claridad y simplicidad en el sistema.

En la mayoría de los sistemas tipo Unix, todos los procesos de una tubería se inician simultáneamente, con sus flujos conectados adecuadamente y gestionados por el planificador junto con todos los demás procesos que se ejecutan en la máquina. Un aspecto importante de esto, que distingue a las tuberías de Unix de otras implementaciones de tuberías, es el concepto de almacenamiento en búfer : por ejemplo, un programa emisor puede producir 5000 bytes por segundo , y un programa receptor solo puede aceptar 100 bytes por segundo, pero no se pierde ningún dato. En cambio, la salida del programa emisor se almacena en el búfer. Cuando el programa receptor está listo para leer datos, el siguiente programa en la tubería lee del búfer. Si el búfer está lleno, el programa emisor se detiene (bloquea) hasta que el receptor extraiga al menos algunos datos del búfer. En Linux, el tamaño del búfer es de 16 páginas , equivalente a 65 536 bytes (64  KiB) en la mayoría de los sistemas. [ 11 ]

tuberías de red

Herramientas como netcat y socat pueden conectar tuberías a sockets TCP/IP .

Tuberías en interfaces de línea de comandos

Todas las shells de Unix de uso generalizado cuentan con una sintaxis especial para la creación de tuberías. En todos los casos, los comandos se escriben secuencialmente, separados por la barra vertical ASCII (que, por esta razón, suele denominarse "barra vertical"). La shell inicia los procesos y establece las conexiones necesarias entre sus flujos estándar (incluido cierto almacenamiento en búfer ).|

La canalización utiliza tuberías anónimas . En las tuberías anónimas, los datos escritos por un proceso son almacenados en búfer por el sistema operativo hasta que son leídos por el siguiente proceso, y este canal unidireccional desaparece cuando los procesos finalizan; esto difiere de las tuberías con nombre , donde los mensajes se pasan hacia o desde una tubería que se nombra convirtiéndola en un archivo, y permanece después de que los procesos finalizan. La sintaxis estándar de la shell para tuberías anónimas consiste en enumerar varios comandos, separados por barras verticales ("pipes" en la terminología común de Unix):

comando1 | comando2 | comando3 

Por ejemplo, para listar los archivos en el directorio actual ( ls ), conservar solo las líneas de la salida de ls que contienen la cadena "key" ( grep ) y ver el resultado en una página desplazable ( less ), un usuario escribe lo siguiente en la línea de comandos de una terminal:

ls -l | grep key | less 

El comando ls -lse ejecuta como un proceso, cuya salida (stdout) se canaliza a la entrada (stdin) del proceso para grep key; y de igual manera para el proceso para less. Cada proceso toma la entrada del proceso anterior y produce la salida para el siguiente proceso a través de flujos estándar . Cada |le indica al intérprete de comandos que conecte la salida estándar del comando de la izquierda con la entrada estándar del comando de la derecha mediante un mecanismo de comunicación entre procesos llamado tubería (anónima) , implementado en el sistema operativo. Las tuberías son unidireccionales; los datos fluyen a través de la tubería de izquierda a derecha.

Ejemplo

A continuación se muestra un ejemplo de una canalización que implementa una especie de corrector ortográfico para el recurso web indicado por una URL . A continuación se explica su funcionamiento.

curl 'https://en.wikipedia.org/wiki/Pipeline_(Unix)' |sed 's/[^a-zA-Z ]/ /g' |tr 'AZ ' 'az\n' |grep '[az]' |ordenar -u |comm -23 - < ( ordenar /usr/share/dict/words ) |menos 
  1. curlObtiene el contenido HTML de una página web (podría usarse wgeten algunos sistemas).
  2. sedSustituye por espacios todos los caracteres (del contenido de la página web) que no sean espacios ni letras. ( Se conservan los saltos de línea ).
  3. trCambia todas las letras mayúsculas a minúsculas y convierte los espacios en las líneas de texto en saltos de línea (cada 'palabra' ahora está en una línea separada).
  4. grepIncluye únicamente las líneas que contienen al menos un carácter alfabético en minúscula (eliminando las líneas en blanco).
  5. sortordena la lista de 'palabras' alfabéticamente y el -uinterruptor elimina los duplicados.
  6. commencuentra líneas en común entre dos archivos, -23suprime las líneas únicas del segundo archivo y las que son comunes a ambos, dejando solo las que se encuentran únicamente en el primer archivo nombrado. El -en lugar de un nombre de archivo hace commque use su entrada estándar (desde la tubería en este caso). sort /usr/share/dict/wordsordena el contenido del wordsarchivo alfabéticamente, como commse espera, y <( ... )genera los resultados en un archivo temporal (a través de la sustitución de procesos ), que commlee. El resultado es una lista de palabras (líneas) que no se encuentran en /usr/share/dict/words.
  7. lessPermite al usuario navegar por los resultados.

Flujo de errores

Por defecto, los flujos de error estándar (" stderr ") de los procesos en una tubería no se pasan a través de la tubería; en su lugar, se fusionan y se dirigen a la consola . Sin embargo, muchos shells tienen sintaxis adicional para cambiar este comportamiento. En el shell csh|& , por ejemplo, usar en lugar de |significa que el flujo de error estándar también debe fusionarse con la salida estándar y pasarse al siguiente proceso. El shell Bash también puede fusionar el error estándar con |&desde la versión 4.0 [ 12 ] o usando 2>&1, así como redirigirlo a un archivo diferente.

Tubería

En las canalizaciones simples más comunes, el intérprete de comandos conecta una serie de subprocesos mediante tuberías y ejecuta comandos externos dentro de cada subproceso. Por lo tanto, el intérprete de comandos no procesa directamente los datos que fluyen a través de la canalización.

Sin embargo, es posible que el intérprete de comandos realice el procesamiento directamente, utilizando un llamado molino o molino de tuberías (ya que whilese utiliza un comando para "fresar" los resultados del comando inicial). Esta estructura generalmente se ve así:

comando | mientras lee -r var1 var2 ... ; hacer # procesar cada línea, usando las variables analizadas como var1, var2, etc. # (tenga en cuenta que esto puede ser un subproceso: var1, var2, etc. no estarán disponibles # después de que termine el bucle while; algunos shells, como zsh y versiones más recientes # de Korn shell, procesan los comandos a la izquierda del operador de tubería # en un subproceso) hecho

Tal pipemill puede no funcionar como se espera si el cuerpo del bucle incluye comandos, como caty ssh, que leen de stdin: [ 13 ] en la primera iteración del bucle, dicho programa (llamémoslo el drenador ) leerá la salida restante de command, y el bucle terminará (con resultados que dependen de las especificidades del drenador). Hay un par de maneras posibles de evitar este comportamiento. Primero, algunos drenadores admiten una opción para deshabilitar la lectura de stdin(por ejemplo ssh -n). Alternativamente, si el drenador no necesita leer ninguna entrada de stdinpara hacer algo útil, se puede proporcionar < /dev/nullcomo entrada.

Como todos los componentes de una tubería se ejecutan en paralelo, un intérprete de comandos normalmente bifurca un subproceso (un subproceso) para gestionar su contenido, lo que imposibilita la propagación de cambios de variables al entorno externo del intérprete. Para solucionar este problema, el "pipemill" puede alimentarse desde un documento here que contenga una sustitución de comando , la cual espera a que la tubería termine de ejecutarse antes de procesar su contenido. Alternativamente, se puede utilizar una tubería con nombre o una sustitución de proceso para la ejecución en paralelo. GNU bash también tiene una lastpipeopción para deshabilitar la bifurcación del último componente de la tubería. [ 14 ]

Creación programática de pipelines

Las tuberías se pueden crear bajo control de programa. La pipe()llamada al sistema Unix solicita al sistema operativo que construya un nuevo objeto de tubería anónima . Esto da como resultado dos descriptores de archivo nuevos y abiertos en el proceso: el extremo de solo lectura de la tubería y el extremo de solo escritura. Los extremos de la tubería parecen descriptores de archivo anónimos normales , excepto que no tienen capacidad de búsqueda.

Para evitar bloqueos y aprovechar el paralelismo, el proceso Unix con una o más tuberías nuevas generalmente creará fork()nuevos procesos. Cada proceso cerrará los extremos de la tubería que no utilice antes de producir o consumir datos. Alternativamente, un proceso podría crear nuevos hilos y usar la tubería para comunicarse entre ellos.

También se pueden crear tuberías con nombremkfifo() utilizando omknod()y luego presentarlas como archivo de entrada o salida a los programas cuando se invocan. Permiten crear tuberías de múltiples rutas y son especialmente eficaces cuando se combinan con la redirección de error estándar o contee.

Hasta la llegada de MacOS Tahoe , el robot del icono de Automator de Apple , que también utiliza un concepto de tubería para encadenar comandos repetitivos, sostenía una tubería en homenaje al concepto original de Unix.

En otros idiomas

Las tuberías se pueden usar en C++ . C++20 introduce operator|(el operador de tubería) y permite operaciones de encadenamiento al estilo LINQ con los std::rangesespacios de nombres. std::viewscontiene varias clases que se invocan a través de operator(). [ 15 ]

using std :: vector ; using std :: ranges :: to ; using std :: views :: filter ; using std :: views :: transform ;vector < int > números = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };// Pipeline: filtra los números pares, los duplica y luego suma el vector resultante < int > resultado = números | filtro ([]( int n ) -> bool { return n % 2 == 0 ; }) | transformar ([]( int n ) -> int { return n * 2 ; }) | a < vector > ();

Véase también

Referencias

  1. "La creación del sistema operativo UNIX" . Bell Labs. Archivado del original el 14 de septiembre de 2004.
  2. 1 2 McIlroy, MD (1987). Un lector de Research Unix: extractos anotados del Manual del programador, 1971–1986 (PDF) (Informe técnico). CSTR. Bell Labs. 139.
  3. Thompson K , Ritchie DM (febrero de 1973). Manual del programador de UNIX, tercera edición (PDF) (Informe técnico) (3.ª ed.). Bell Labs. pág. 178.  
  4. Mahoney, Michael S. "El proyecto de historia oral de Unix: Release.0, el comienzo" . McIlroy: Fue uno de los pocos lugares donde casi ejercí control gerencial sobre Unix, estaba presionando para que se implementaran esas cosas, sí.
  5. "Petroglifos proféticos" . www.bell-labs.com . Archivado del original el 8 de mayo de 1999. Consultado el 22 de mayo de 2022 .
  6. "Pipes: Una breve introducción" . The Linux Information Project. 23 de agosto de 2006 [Creado el 29 de abril de 2004] . Consultado el 7 de enero de 2024 .
  7. "Dartmouth Timesharing" (DOC) . Instituto Tecnológico de Rochester . Consultado el 7 de enero de 2024 .
  8. "Datos" . www.bell-labs.com . Archivado del original el 20 de febrero de 1999. Consultado el 22 de mayo de 2022 .
  9. Cox, Russ. "Bell Labs y CSP Threads" . Switchboard . Consultado el 7 de enero de 2024 .
  10. Ritchie y Thompson, 1974
  11. Manual del programador de Linux – Descripción general, convenciones y miscelánea de Manned.orgpipe(7)  
  12. "Notas de la versión de Bash" . tiswww.case.edu . Consultado el 14 de junio de 2017 .
  13. "Interacción de bucles de shell con SSH" . 6 de marzo de 2012. Archivado del original el 6 de marzo de 2012.
  14. John1024. "¿Cómo puedo almacenar los resultados del comando "find" como un array en Bash?" . Stack Overflow .{{cite web}}: CS1 maint: nombres numéricos: lista de autores ( enlace )
  15. "Biblioteca de rangos (desde C++20) - cppreference.com" . cppreference.com . Consultado el 4 de septiembre de 2025 .
  • Historia de la notación de tuberías de Unix. Archivado el 8 de abril de 2015 en Wayback Machine.
    • El memorándum original de Doug McIlroy de 1964 , en el que proponía por primera vez el concepto de pipa.
  • pipe: crear un canal entre procesos Referencia de interfaces del sistema, Especificación única de UNIX , Versión 5 de The Open Group   
  • Tuberías: Una breve introducción del Proyecto de Información de Linux (LINFO)
  • Tuberías Unix: un paradigma de programación potente y elegante (Softpanorama)
  • Análisis de datos ad hoc desde la línea de comandos de Unix en Wikibooks : muestra cómo utilizar secuencias de comandos compuestas por filtros simples para realizar análisis de datos complejos.
  • Uso y abuso de tuberías con datos de audio : ofrece una introducción al uso y abuso de tuberías con netcat, nettee y fifos para reproducir audio a través de una red.
  • stackoverflow.com – Preguntas y respuestas sobre el manejo de tuberías en bash.