Apuntes mientras aprendo sobre software y computadoras.

Linux

¿Qué son las Pipelines en Bash?

En este apunte ultra rápido voy a estudiar qué son las Pipelines en Bash.

Antes de empezar, y a modo de auto publicidad, este texto forma parte de mi “Guía mínima para empezar a programar en Bash”. Si te interesa leer a un principiante en programación aprender sobre el tema, ese es el lugar indicado.

Pero es importante también tener en cuenta que este aspecto de la terminal no solamente sirven al momento de programar en Bash. Casi cualquier comando puede verse enriquecido por su uso.

Así que sin más más vueltas:

¿Qué son las Pipelines en Bash?

Bueno, luego de una veloz busca en el diccionario ahora se que, entre otras cosas, la palabra “pipeline” en castellano significa una tubería.

Y siendo que estoy hablando de pipelines y la shell, puedo intuir que la terminal me permite crear tuberías.

A decir verdad, eso no explica mucho… mejor reviso el manual de Bash. Ahí dice lo siguiente:

A pipeline is a sequence of one or more commands separated by one of the control operators ‘|’ or ‘|&’.

manual de bash

Lo quiere decir: una pipeline es una secuencia de uno o más comandos, separados por uno de los operadores de control “|” o también “|&”.

Otra vez, puedo seguir intuyendo que una pipeline es una tubería que conecta a uno o más comandos.

Pero ¿cómo los conecta?

Si lo reviso de manera superficial, lo que me voy a encontrar es algo así como “dos comandos entubados” por un símbolo. En la terminal queda así:

[time [-p]] [!] command1 [ | or |& command2 ] …

O para simplificar:

comando1 | comando2

El símbolo | (barra vertical o pleca) es uno de los dos que puedo utilizar para crear una pipeline.

¿Qué consigo con esto?

El manual de Bash profundiza con el siguiente párrafo:

The output of each command in the pipeline is connected via a pipe to the input of the next command. That is, each command reads the previous command’s output.

manual de bash

En mi traducción literal: “El output (la salida) de cada comando esta conectado por una tubería al input (la entrada) del comando siguiente. Esto es, cada comando lee de la salida del comando anterior.”

Esto es, utilizando pipelines obtengo que el output (el resultado) de un primer comando se transforme en el input (el dato para ingresar) en comando que sigue.

Pensado de este modo, quieren decir que la información viaja de un lado a otro. De un comando a otro.

Voy a probarlo con un ejemplo.

Por una parte tengo el comando“ls”, el cual me da una lista de los archivos en un directorio.

~$ ls
Desktop
Music
Pictures
Public
Videos

Por otra parte, el comando “sort -R” ordena al azar cualquier input que le entregue. ¿Qué ocurre si lo añado con una pipeline al comando anterior?

Esto se puede escribir y repasar directamente en la terminal:

ls | sort -R
Public
Music
Videos
Pictures
Desktop

Al hacer esto, consigo redirigir el resultado de “ls” (los nombres de los archivos en el directorio) para que esa información se convierta en la entrada del comando “sort”. Esto me va a entregar una lista desordenada al azar de los nombres de los archivos en la carpeta.

Es cierto, tal vez no sea el ejemplo más práctico… pero no pueden negar que funciona para ver lo entender lo que esta pasando.

Vale agregar que puedo usar múltiples pipelines seguidas, encadenando la entrada y salida de información entre múltiples comandos.

Por ejemplo, el comando “cat” acompañado de la opción “-n” (“–number” o numerar) le agrega un número a cada linea que le entreguemos por input. Si lo añado por una pipeline al ejemplo anterior, eso me queda:

ls | sort -R | cat -n
1 Videos
2 Public
3 Desktop
4 Music
5 Pictures

De este modo puedo encadenar la entrada y la salida de varios comandos a la vez.

Algunas otras variantes para una pipeline:

Antes mencioné que se puede crear una pipeline con una barra vertical “|”, pero que también se puede hacer con “|&”… ¿Cuál es la diferencia?

El manual de bash dice:

If ‘|&’ is used, command1’s standard error, in addition to its standard output, is connected to command2’s standard input through the pipe (…)

Y básicamente esto lo entiendo del siguiente modo. Si se utiliza “|&”, también se va a tener en cuenta un resultado de error del comando1 como una entrada para el comando2.

Pensado de otro modo. Si hago una pipeline con una barra vertical “|”, la cadena se corta en el comando donde ocurre el error.

Por ejemplo, si yo escribo el comando “touch” en la terminal obtengo por resultado:

touch
touch: missing file operand
Try 'touch --help' for more information.

Esto es, que al comando “touch” le falta información y que puedo buscar màs informaciòn sobre como funciona con ‘touch –help’.

Ahora si intento encadenar esto:

touch | cat --number
touch: missing file operand
Try 'touch --help' for more information.

Puedo notar que la pipeline se termina cuando aparece el primer error y el comando “cat -n” nunca se ejecuta.

Pero caso contrario, si realizo una pipeline por medio de “|&”, la cadena no se detiene en el comando donde ocurre el error. Por ejemplo:

touch |& cat --number
1 touch: missing file operand
2 Try 'touch --help' for more information.

En ese último caso, la pipeline siguió por medio del error y pasó al siguiente comando. Haciendo esto, “cat –number” le agregó un número de linea a cada renglón de la entrada.

Conclusión:

Este es un tema que aparece en muchas oportunidades cuando estudiamos sobre Linux. Por eso espero que te sirva de utilidad si estas buscando saber qué son las Pipelines en Bash.

Siempre estoy tratando de mejorar el texto, por lo que intento ampliarlo al aprender cosas nuevas. Y si encontrás algún error en el texto o los ejemplos, te pido por favor que me avises para que pueda corregirlo.

La seguimos en el próximo apunte.

Recursos:

– Manual de bash, seccion dedicada a las pipelines (en inglés)

Dejar una respuesta