Linux Professional Institute Learning Logo.
Pasar al contenido principal
  • Inicio
    • Todos los recursos
    • LPI Learning Materials
    • Conviértete en colaborador
    • Publishing Partners
    • Conviértase en un Publishing Partner
    • Acerca de nosotros
    • FAQ
    • Colaboradores
    • Roadmap
    • Contáctenos
  • LPI.org
103.4 Lección 2
Tema 101: Arquitectura del Sistema
101.1 Determinar y configurar los ajustes de hardware
  • 101.1 Lección 1
101.2 Arranque del sistema
  • 101.2 Lección 1
101.3 Cambiar los niveles de ejecución / objetivos de arranque y apagar o reiniciar el sistema
  • 101.3 Lección 1
Tema 102: Instalación de Linux y gestión de paquetes
102.1 Diseño del esquema de particionado del disco duro duro
  • 102.1 Lección 1
102.2 Instalar un gestor de arranque
  • 102.2 Lección 1
102.3 Gestión de librerías compartidas
  • 102.3 Lección 1
102.4 Gestión de paquetes Debian
  • 102.4 Lección 1
102.5 Gestión de paquetes RPM y YUM
  • 102.5 Lección 1
102.6 Linux como sistema virtualizado
  • 102.6 Lección 1
Tema 103: Comandos GNU y Unix
103.1 Trabajar desde la línea de comandos
  • 103.1 Lección 1
  • 103.1 Lección 2
103.2 Procesar secuencias de texto usando filtros
  • 103.2 Lección 1
103.3 Administración básica de archivos
  • 103.3 Lección 1
  • 103.3 Lección 2
103.4 Uso de secuencias de texto, tuberías y redireccionamientos
  • 103.4 Lección 1
  • 103.4 Lección 2
103.5 Crear, supervisar y matar procesos
  • 103.5 Lección 1
  • 103.5 Lección 2
103.6 Modificar la prioridad de ejecución de los procesos
  • 103.6 Lección 1
103.7 Realizar búsquedas en archivos de texto usando expresiones regulares
  • 103.7 Lección 1
  • 103.7 Lección 2
103.8 Edición básica de archivos
  • 103.8 Lección 1
Tema 104: Dispositivos, sistemas de archivos Linux y el estándar de jerarquía de archivos
104.1 Creación de particiones y sistemas de archivos
  • 104.1 Lección 1
104.2 Mantener la integridad de los sistemas de archivos
  • 104.2 Lección 1
104.3 Controlar el montaje y desmontaje de los sistemas de archivos
  • 104.3 Lección 1
104.5 Administración de los permisos y los propietarios de los archivos
  • 104.5 Lección 1
104.6 Crear y cambiar enlaces duros y simbólicos
  • 104.6 Lección 1
104.7 Encontrar archivos de sistema y ubicar archivos en el lugar correspondiente
  • 104.7 Lección 1
How to get certified
  1. Tema 103: Comandos GNU y Unix
  2. 103.4 Uso de secuencias de texto, tuberías y redireccionamientos
  3. 103.4 Lección 2

103.4 Lección 2

Certificación:

LPIC-1 (101)

Versión:

5.0

Tema:

103 Comandos GNU y Unix

Objetivo:

103.4 Usar flujos, tuberías y redireccionamientos

Lección:

2 de 2

Introducción

Un aspecto de la filosofía de Unix establece que cada programa debe tener un propósito específico y no debe tratar de incorporar características fuera de su alcance. Pero mantener las cosas simples no significa resultados menos elaborados, ya que se pueden encadenar diferentes programas para producir un resultado combinado. El caracter de barra vertical |, también conocido como el símbolo pipe, se puede usar para crear una tubería que conecte la salida de un programa directamente a la entrada de otro, mientras que command substitution permite almacenar la salida de un programa en una variable o usarlo directamente como argumento para otro comando.

Tuberías (Pipes)

A diferencia de los redireccionamientos, con las tuberías los datos fluyen de izquierda a derecha en la línea de comandos y el objetivo es otro proceso, no una ruta del sistema de archivos, un descriptor de archivo o un documento. El carácter de canalización | le dice al shell que inicie todos los comandos distintos al mismo tiempo y que conecte la salida del comando anterior a la entrada del siguiente comando, de izquierda a derecha. Por ejemplo, en lugar de utilizar redireccionamientos, el contenido del archivo /proc/cpuinfo enviado a la salida estándar por cat puede canalizarse al stdin de wc con el siguiente comando:

$ cat /proc/cpuinfo | wc
   208    1184    6096

En ausencia de una ruta a un archivo, wc cuenta el número de líneas, palabras y caracteres que recibe en su stdin, como es el caso en el ejemplo. Muchas tuberías pueden estar presentes en un comando compuesto. En el siguiente ejemplo, se utilizan dos tuberías:

$ cat /proc/cpuinfo | grep 'model name' | uniq
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

El contenido del archivo /proc/cpuinfo producido por cat /proc/cpuinfo se canalizó al comando grep 'model name', que luego selecciona solo las líneas que contienen el término model name. La máquina que ejecuta el ejemplo tiene muchas CPU, por lo que hay líneas repetidas con model name. La última tubería conecta el nombre del modelo grep 'model name' a uniq, que es responsable de omitir cualquier línea igual a la anterior.

Las tuberías se pueden combinar con redireccionamientos en la misma línea de comando. El ejemplo anterior se puede reescribir en una forma más simple:

$ grep 'model name' </proc/cpuinfo | uniq
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

La redirección de entrada para grep no es estrictamente necesaria ya que grep acepta una ruta de archivo como argumento, pero el ejemplo demuestra cómo construir dichos comandos combinados.

Las tuberías y redirecciones son exclusivas, es decir, una fuente puede asignarse a un solo destino. Sin embargo, es posible redirigir una salida a un archivo y aún verlo en la pantalla con el programa tee. Para hacerlo, el primer programa envía su salida al stdin de tee y se le proporciona un nombre de archivo a este último para almacenar los datos:

$ grep 'model name' </proc/cpuinfo | uniq | tee cpu_model.txt
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz
$ cat cpu_model.txt
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

El resultado del último programa de la cadena, generado por uniq, se muestra y almacena en el archivo cpu_model.txt. Para no sobrescribir el contenido del archivo proporcionado sino para agregarle datos, la opción -a debe proporcionarse a tee.

Solo la salida estándar de un proceso es capturada por una tubería. Digamos que debe pasar por un largo proceso de compilación en la pantalla y al mismo tiempo guardar tanto la salida estándar como el error estándar en un archivo para su posterior inspección. Suponiendo que su directorio actual no tiene un Makefile, el siguiente comando generará un error:

$ make | tee log.txt
make: *** No targets specified and no makefile found.  Stop.

Aunque se muestra en la pantalla, el mensaje de error generado por make no fue capturado por tee y el archivo log.txt se creó vacío. Se debe hacer una redirección antes de que una tubería pueda capturar el stderr:

$ make 2>&1 | tee log.txt
make: *** No targets specified and no makefile found.  Stop.
$ cat log.txt
make: *** No targets specified and no makefile found.  Stop.

En este ejemplo, el stderr de make se redirigió al stdout, por lo que tee pudo capturarlo con una tubería, mostrarlo en la pantalla y guardarlo en el archivo log.txt. En casos como este, puede ser útil guardar los mensajes de error para su posterior inspección.

Sustitución de comando

Otro método para capturar la salida de un comando es command substitution (sustitución de comando). Al colocar un comando dentro de las comillas inversas, Bash lo reemplaza con su salida estándar. El siguiente ejemplo muestra cómo usar el stdout de un programa como argumento para otro programa:

$ mkdir `date +%Y-%m-%d`
$ ls
2019-09-05

La salida del programa date, la fecha actual formateada como año-mes-día, se utilizó como argumento para crear un directorio con mkdir. Se obtiene un resultado idéntico usando $() en lugar de comillas inversas:

$ rmdir 2019-09-05
$ mkdir $(date +%Y-%m-%d)
$ ls
2019-09-05

El mismo método puede usarse para almacenar la salida de un comando como una variable:

$ OS=`uname -o`
$ echo $OS
GNU/Linux

El comando uname -o genera el nombre genérico del sistema operativo actual, que estaba almacenado en la variable de sesión OS. Asignar la salida de un comando a una variable es muy útil en los scripts, ya que permite almacenar y evaluar los datos de muchas maneras distintas.

Dependiendo de la salida generada por el comando reemplazado, la sustitución del comando incorporado puede no ser apropiada. Un método más sofisticado para usar la salida de un programa como argumento de otro programa emplea un intermediario llamado xargs. El programa xargs usa los contenidos que recibe a través de stdin para ejecutar un comando dado con los contenidos como argumento. El siguiente ejemplo muestra xargs ejecutando el programa identify con argumentos proporcionados por el programa find:

$ find /usr/share/icons -name 'debian*' | xargs identify -format "%f: %wx%h\n"
debian-swirl.svg: 48x48
debian-swirl.png: 22x22
debian-swirl.png: 32x32
debian-swirl.png: 256x256
debian-swirl.png: 48x48
debian-swirl.png: 16x16
debian-swirl.png: 24x24
debian-swirl.svg: 48x48

El programa identify es parte de ImageMagick, un conjunto de herramientas de línea de comandos para inspeccionar, convertir y editar la mayoría de los tipos de archivos de imagen. En el ejemplo, xargs tomó todas las rutas listadas por find y las puso como argumentos para identify, que luego muestra la información para cada archivo formateado como lo requiere la opción -format. Los archivos encontrados por find en el ejemplo son imágenes que contienen el logotipo de distribución en un sistema de archivos Debian. -format es un parámetro para identify, no para xargs.

La opción -n 1 requiere que xargs ejecute el comando dado con un solo argumento a la vez. En el caso del ejemplo, en lugar de pasar todas las rutas encontradas por find como una lista de argumentos para identify, usar xargs -n 1 ejecutaría el comando identify para cada ruta por separado. El uso de -n 2 ejecutaría identify con dos rutas como argumentos, -n 3 con tres rutas como argumentos y así sucesivamente. De manera similar, cuando xargs procesa contenidos de varias líneas, como es el caso de la entrada proporcionada por find, la opción -L puede usarse para limitar cuántas líneas se usarán como argumentos por ejecución de comando.

Note

Usar xargs con la opción -n 1 o -L 1 para procesar la salida generada por find puede ser innecesario El comando find tiene la opción -exec para ejecutar un comando dado para cada elemento de resultado de búsqueda.

Si las rutas tienen caracteres de espacio, es importante ejecutar find con la opción -print0. Esta opción indica a find que use un carácter nulo entre cada entrada para que la lista pueda ser analizada correctamente por xargs (se suprimió la salida):

$ find . -name '*avi' -print0 -o -name '*mp4' -print0 -o -name '*mkv' -print0 | xargs -0 du | sort -n

La opción -0 le dice a xargs que el caracter nulo debe usarse como separador. De esa manera, las rutas de archivo proporcionadas por find se analizan correctamente incluso si tienen caracteres en blanco u otros caracteres especiales. El ejemplo anterior muestra cómo usar el comando du para averiguar el espacio ocupado en disco de cada archivo encontrado y luego ordenar los resultados por tamaño. La salida fue suprimida por concisión. Tenga en cuenta que para cada criterio de búsqueda es necesario colocar la opción -print0 para find.

Por defecto, xargs coloca los argumentos del comando ejecutado en último lugar. Para cambiar ese comportamiento, se debe usar la opción -I:

$ find . -mindepth 2 -name '*avi' -print0 -o -name '*mp4' -print0 -o -name '*mkv' -print0 | xargs -0 -I PATH mv PATH ./

En el último ejemplo, cada archivo encontrado por find se mueve al directorio actual. Como las rutas de origen deben ser informadas a mv antes de la ruta de destino, se da un término de sustitución a la opción -I de xargs que luego se coloca apropiadamente junto a mv. Al utilizar el caracter nulo como separador, no es necesario encerrar el término de sustitución con comillas.

Ejercicios Guiados

  1. Es conveniente guardar la fecha de ejecución de las acciones realizadas por scripts automatizados. El comando date +%Y-%m-%d muestra la fecha actual en formato año-mes-día. ¿Cómo se puede almacenar la salida de dicho comando en una variable de shell llamada TODAY usando la sustitución de comandos?

  2. Usando el comando echo, ¿cómo se puede enviar el contenido de la variable TODAY a la entrada estándar del comando sed s/-/./g?

  3. ¿Cómo podría usarse la salida del comando date +%Y-%m-%d como una cadena Here para ordenar sed s/-/./g?

  4. El comando convert image.jpeg -resize 25% small/image.jpeg crea una versión más pequeña de image.jpeg y coloca la imagen resultante en un archivo con el mismo nombre dentro del subdirectorio small. Usando xargs, ¿cómo es posible ejecutar el mismo comando para cada imagen listada en el archivo filelist.txt?

Ejercicios Exploratorios

  1. Una rutina de copia de seguridad simple crea periódicamente una imagen de partición /dev/sda1 con dd < /dev/sda1 > sda1.img. Para realizar futuras comprobaciones de integridad de datos, la rutina también genera un hash SHA1 del archivo con sha1sum < sda1.img > sda1.sha1. Al agregar tuberías y el comando tee, ¿cómo se combinarían estos dos comandos en uno?

  2. El comando tar se usa para archivar muchos archivos en uno solo, preservando la estructura del directorio. La opción -T permite especificar un archivo que contiene las rutas a archivar. Por ejemplo, find /etc -type f | tar -cJ -f /srv/backup/etc.tar.xz -T - crea un archivo tar comprimido etc.tar.xz de la lista provista por el comando find (la opción -T- indica la entrada estándar como la lista de ruta). Para evitar posibles errores de análisis debido a las rutas que contienen espacios, ¿qué opciones de comando deberían estar presentes para find y tar?

  3. En lugar de abrir una nueva sesión de shell remota, el comando ssh solo puede ejecutar un comando indicado como argumento: ssh user@storage "remote command". Dado que ssh también permite redirigir la salida estándar de un programa local a la entrada estándar del programa remoto, ¿cómo canalizaría el comando cat un archivo local llamado etc.tar.gz a /srv/backup/etc.tar.gz en user@storage a través de ssh?

Resumen

Esta lección cubre las técnicas tradicionales de comunicación entre procesos empleadas por Linux. La canalización de comandos crea un canal de comunicación unidireccional entre dos procesos y la sustitución de comandos permite almacenar la salida de un proceso en una variable de shell. La lección sigue los siguientes pasos:

  • Cómo se pueden usar pipes para transmitir la salida de un proceso a la entrada de otro.

  • El propósito de los comandos tee y xargs.

  • Cómo capturar el resultado de un proceso con command sustitution, almacenándolo en una variable o usándolo directamente como parámetro para otro comando.

Los comandos y procedimientos abordados fueron:

  • Comando de canalización con |.

  • Sustitución de comandos con backticks y $().

  • Comandos tee, xargs y find.

Respuestas a los ejercicios guiados

  1. Es conveniente guardar la fecha de ejecución de las acciones realizadas por scripts automatizados. El comando date +%Y-%m-%d muestra la fecha actual en formato año-mes-día. ¿Cómo se puede almacenar la salida de dicho comando en una variable de shell llamada TODAY usando la sustitución de comandos?

    $ TODAY=`date +%Y-%m-%d`

    o

    $ TODAY=$(date +%Y-%m-%d)
  2. Usando el comando echo, ¿cómo se puede enviar el contenido de la variable TODAY a la entrada estándar del comando sed s/-/./g?

    $ echo $TODAY | sed s/-/./g
  3. ¿Cómo podría usarse la salida del comando date +%Y-%m-%d como una cadena Here para ordenar sed s/-/./g?

    $ sed s/-/./g <<< `date +%Y-%m-%d`

    o

    $ sed s/-/./g <<< $(date +%Y-%m-%d)
  4. El comando convert image.jpeg -resize 25% small/image.jpeg crea una versión más pequeña de image.jpeg y coloca la imagen resultante en un archivo con el mismo nombre dentro del subdirectorio small. Usando xargs, ¿cómo es posible ejecutar el mismo comando para cada imagen listada en el archivo` filelist.txt`?

    $ xargs -I IMG convert IMG -resize 25% small/IMG < filelist.txt

    o

    $ cat filelist.txt | xargs -I IMG convert IMG -resize 25% small/IMG

Respuestas a ejercicios exploratorios

  1. Una rutina de copia de seguridad simple crea periódicamente una imagen de partición /dev/sda1 con dd < /dev/sda1 > sda1.img. Para realizar futuras comprobaciones de integridad de datos, la rutina también genera un hash SHA1 del archivo con sha1sum < sda1.img > sda1.sha1. Al agregar tuberías y el comando tee, ¿cómo se combinarían estos dos comandos en uno?

    # dd < /dev/sda1 | tee sda1.img | sha1sum > sda1.sha1
  2. El comando tar se usa para archivar muchos archivos en uno solo, preservando la estructura del directorio. La opción -T permite especificar un archivo que contiene las rutas a archivar. Por ejemplo, find /etc -type f | tar -cJ -f /srv/backup/etc.tar.xz -T - crea un archivo tar comprimido etc.tar.xz de la lista provista por el comando find (la opción -T- indica la entrada estándar como la lista de ruta). Para evitar posibles errores de análisis debido a las rutas que contienen espacios, ¿qué opciones de comando deberían estar presentes para find y tar?

    Opciones -print0 y --null:

    $ find /etc -type f -print0 | tar -cJ -f /srv/backup/etc.tar.xz --null -T -
  3. En lugar de abrir una nueva sesión de shell remota, el comando ssh solo puede ejecutar un comando indicado como argumento: ssh user@storage "remote command". Dado que ssh también permite redirigir la salida estándar de un programa local a la entrada estándar del programa remoto, ¿cómo canalizaría el comando cat un archivo local llamado etc.tar.gz a /srv/backup/etc.tar.gz en user@storage a través de ssh?

    $ cat etc.tar.gz | ssh user@storage "cat > /srv/backup/etc.tar.gz"

    o

    $ ssh user@storage "cat > /srv/backup/etc.tar.gz" < etc.tar.gz

Linux Professional Insitute Inc. Todos los derechos reservados. Visite el sitio web de Learning Materials: https://learning.lpi.org
Este trabajo está registrado bajo la Licencia Internacional Creative Commons Attribution-NonCommercial-NoDerivatives 4.0

Siguiente lección

103.5 Crear, supervisar y matar procesos (103.5 Lección 1)

Leer la próxima lección

Linux Professional Insitute Inc. Todos los derechos reservados. Visite el sitio web de Learning Materials: https://learning.lpi.org
Este trabajo está registrado bajo la Licencia Internacional Creative Commons Attribution-NonCommercial-NoDerivatives 4.0

LPI es una organización sin fines de lucro.

© 2023 Linux Professional Institute (LPI) es la organización global de certificación y apoyo académico para profesionales de código abierto. Con más de 200,000 titulares de certificación, es el primer y más grande organismo de certificación no comercial del mundo para Linux y Open Source. LPI cuenta con profesionales certificados en más de 180 países, realiza exámenes en varios idiomas y tiene cientos de socios de capacitación.

Nuestro propósito es hacer que las oportunidades económicas y creativas estén disponibles para todos, haciendo que el conocimiento de código abierto y la certificación sea universalmente accesible.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Contáctenos
  • Política de privacidad y cookies

¿Detecta un error o desea ayudar a mejorar esta página? Por favor háznoslo saber.

© 1999–2023 The Linux Professional Institute Inc. Todos los derechos reservados.