Use tuberías de Linux para coreografiar cómo colaboran las utilidades de la línea de comandos. Simplifique procesos complejos y aumente su productividad aprovechando una colección de comandos independientes y convirtiéndolos en un equipo con un solo propósito. Te mostramos cómo.
Las tuberías están en todas partes
Las canalizaciones son una de las características de línea de comandos más útiles que disponen los sistemas operativos Linux y tipo Unix. Las tuberías se usan de innumerables formas. Mire cualquier artículo de línea de comandos de Linux, en cualquier portal web, no solo en el nuestro, y verá que las tuberías aparecen la mayoría de las veces. Revisé algunos de los posts de Linux de How-To Geek, y en todos ellos se usan tuberías, de una forma u otra.
Las canalizaciones de Linux le posibilitan realizar acciones que no son compatibles con el cascarón. Pero debido a que la filosofía de diseño de Linux es tener muchas pequeñas utilidades que realicen su función dedicada muy bieny sin una funcionalidad innecesaria, el mantra “haz una cosa y hazlo bien”, puedes conectar cadenas de comandos junto con tuberías de modo que la salida de un comando se convierta en la entrada de otro. Cada comando que ingresa aporta su talento único al equipo, y pronto descubrirá que ha reunido un escuadrón ganador.
Un ejemplo simple
Supongamos que tenemos un directorio lleno de muchos tipos diferentes de archivos. Queremos saber cuántos archivos de cierto tipo hay en ese directorio. Hay otras alternativas para hacer esto, pero el objeto de este ejercicio es introducir tuberías, por eso lo haremos con tuberías.
Podemos obtener una lista de los archivos fácilmente usando ls
:
ls
Para separar el tipo de archivo de interés, usaremos grep
. Queremos hallar archivos que tengan la palabra «página» en su nombre de archivo o extensión de archivo.
Usaremos el carácter especial de shell «|
«Para canalizar la salida de ls
dentro grep
.
ls | grep "page"
grep
imprime líneas que coincidir con su patrón de búsqueda. Entonces, esto nos da una lista que contiene solo archivos «.page».
Inclusive este ejemplo trivial muestra la funcionalidad de las tuberías. La salida de ls
no se envió a la ventana de la terminal. Fue enviado a grep
como datos para el grep
comando para trabajar. La salida que vemos proviene de grep,
que es el último comando de esta cadena.
Ampliando nuestra cadena
Comencemos a extender nuestra cadena de comandos canalizados. Podemos contar los archivos «.page» agregando el wc
mando. Usaremos el -l
(recuento de líneas) opción con wc
. Tenga en cuenta que al mismo tiempo hemos agregado el -l
(formato largo) opción para ls
. Lo usaremos en breve.
ls - | grep "page" | wc -l
grep
ya no es el último comando de la cadena, por lo que no vemos su salida. La salida de grep
se alimenta en el wc
mando. La salida que vemos en la ventana del terminal es de wc
. wc
informa que hay 69 archivos “.page” en el directorio.
Extendamos las cosas de nuevo. Tomaremos el wc
comando fuera de la línea de comando y reemplácelo con awk
. Hay nueve columnas en la salida de ls
con el -l
opción (formato largo). Usaremos awk
para imprimir columnas cinco, tres y nueve. Estos son el tamaño, el propietario y el nombre del archivo.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'
Obtenemos una lista de esas columnas, para cada uno de los archivos coincidentes.
Ahora pasaremos esa salida a través del sort
mando. Usaremos el -n
opción (numérica) para dejar sort
saber que la primera columna debe ser tratado como números.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n
La salida ahora está ordenada por tamaño de archivo, con nuestra selección personalizada de tres columnas.
Agregar otro comando
Terminaremos agregando el tail
mando. Le diremos que enumere los últimas cinco líneas de salida solamente.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5
Esto significa que nuestro comando se traduce en algo como «muéstrame los cinco archivos» .page «más grandes de este directorio, ordenados por tamaño». Desde después, no hay ningún comando para lograrlo, pero al usar tuberías, hemos creado las nuestras. Podríamos agregar esto, o cualquier otro comando largo, como un alias o función de shell para guardar toda la escritura.
Aquí está el resultado:
Podríamos invertir el orden de tamaño agregando el -r
opción (inversa) a la sort
comando, y usando head
en lugar de tail
elegir las líneas desde la parte superior de la salida.
Esta vez, los cinco archivos «.page» más grandes se enumeran de mayor a menor:
Algunos ejemplos recientes
Aquí hay dos ejemplos interesantes de posts recientes de How-To geek.
Algunos comandos, como el xargs
comando, están diseñados tener entrada canalizada a ellos. Aquí hay una forma en que podemos tener wc
cuenta los palabras, caracteres y líneas en varios archivos, canalizando ls
dentro xargs
que posteriormente alimenta la lista de nombres de archivo a wc
como si hubieran sido pasados a wc
como parámetros de línea de comando.
ls *.page | xargs wc
El número total de palabras, caracteres y líneas se enumeran en la parte inferior de la ventana de la terminal.
Esta es una forma de obtener una lista ordenada de las extensiones de archivo únicas en el directorio actual, con un recuento de cada tipo.
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c
Están sucediendo muchas cosas aquí.
El resultado muestra la lista de extensiones de archivo, ordenadas alfabéticamente con un recuento de cada tipo único.
Tubos con nombre
Hay otro tipo de tubería disponible para nosotros, llamadas tuberías con nombre. Las tuberías de los ejemplos anteriores se crean sobre la marcha a través de el shell cuando procesa la línea de comandos. Las tuberías se crean, usan y posteriormente se desechan. Son pasajeros y no dejan rastro de sí mismos. Solo existen mientras se esté ejecutando el comando que los utiliza.
Las canalizaciones con nombre aparecen como objetos persistentes en el sistema de archivos, por lo que puede verlas usando ls
. Son persistentes debido a que sobrevivirán a un reinicio de la computadora, aún cuando se descartarán todos los datos no leídos que contengan en ese momento.
Las canalizaciones con nombre se usaron mucho al mismo tiempo para permitir que diferentes procesos envíen y reciban datos, pero no los he visto usados de esa manera por mucho tiempo. Indudablemente, hay gente que aún los utiliza con gran efecto, pero no he encontrado ninguno recientemente. Pero en aras de la integridad, o simplemente para satisfacer su curiosidad, así es como puede usarlos.
Las tuberías con nombre se crean con el mkfifo
mando. Este comando creará una tubería con nombre llamado «geek-pipe» en el directorio actual.
mkfifo geek-pipe
Podemos ver los detalles de la tubería nombrada si usamos el ls
comando con el -l
(formato largo) opción:
ls -l geek-pipe
El primer carácter de la lista es una «p», lo que significa que es una tubería. Si fuera una «d», significaría que el objeto del sistema de archivos es un directorio, y un guión «-» significaría que es un archivo normal.
Usar la tubería con nombre
Usemos nuestra pipa. Las tuberías sin nombre que usamos en nuestros ejemplos anteriores pasaron los datos inmediatamente del comando de envío al comando de recepción. Los datos enviados a través de una canalización con nombre permanecerán en la canalización hasta que se lean. Los datos se guardan verdaderamente en la memoria, por lo que el tamaño de la tubería nombrada no variará en ls
listados si hay datos en él o no.
Usaremos dos ventanas de terminal para este ejemplo. Usaré la etiqueta:
# Terminal-1
en una ventana de terminal y
# Terminal-2
en el otro, para que puedas diferenciarlos. El hash «#» le dice al shell que lo que sigue es un comentario y que lo ignore.
Tomemos la totalidad de nuestro ejemplo anterior y redirigamos eso a la tubería nombrada. Entonces estamos usando canalizaciones con nombre y sin nombre en un comando:
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe
No parecerá que suceda mucho. De todas maneras, puede notar que no regresa al símbolo del sistema, por lo que algo está sucediendo.
En la otra ventana de terminal, emita este comando:
cat < geek-pipe
Estamos redirigiendo el contenido de la tubería nombrada a cat
, por eso eso cat
mostrará ese contenido en la segunda ventana de terminal. Aquí está el resultado:
Y verá que ha regresado al símbolo del sistema en la primera ventana de terminal.
Entonces, ¿qué acaba de pasar?
- Redirigimos algunos resultados a la tubería con nombre.
- La primera ventana de terminal no volvió al símbolo del sistema.
- Los datos permanecieron en la tubería hasta que se leyeron desde la tubería en la segunda terminal.
- Regresamos al símbolo del sistema en la primera ventana de terminal.
Puede estar pensando que podría ejecutar el comando en la primera ventana de terminal como una tarea en segundo plano agregando un &
hasta el final del comando. Y tendrías razón. En ese caso, habríamos regresado al símbolo del sistema de inmediato.
El punto de no El uso del procesamiento en segundo plano fue para resaltar que una tubería con nombre es una procedimiento de bloqueo. Poner algo en una tubería con nombre solo abre un extremo de la tubería. El otro extremo no se abre hasta que el programa de lectura extrae los datos. El kernel suspende el procedimiento en la primera ventana de terminal hasta que los datos se leen desde el otro extremo de la tubería.
El poder de las tuberías
Actualmente, las pipas con nombre son algo así como un acto disruptivo.
Las viejas tuberías de Linux, por otra parte, son una de las herramientas más útiles que puede tener en su kit de herramientas de ventana de terminal. La línea de comandos de Linux comienza a cobrar vida para usted, y obtiene un encendido totalmente nuevo cuando puede orquestar una colección de comandos para producir una actuación cohesiva.
Sugerencia de despedida: es mejor escribir sus comandos canalizados agregando un comando al mismo tiempo y haciendo que esa parte funcione, posteriormente canalizando en el siguiente comando.
setTimeout(function(){
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version=’2.0′;
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s) } (window, document,’script’,
‘https://connect.facebook.net/en_US/fbevents.js’);
fbq(‘init’, ‘335401813750447’);
fbq(‘track’, ‘PageView’);
},3000);