Tuberías y redirecciones en Linux

A estas alturas todos tenemos claros que la línea de comandos tiene un sinfín de utilidades que facilitan nuestro día a día; su combinación con las tuberías y redirecciones, de las que hablaremos hoy, la hacen aún más potente.

Una tubería conecta dos o más comandos, siendo posible una larga cadena de comandos y parámetros. Por ejemplo, si queremos seleccionar una línea o columna exacta de una salida de un registro de actividad, de un número de procesos suministrados por ejemplo por ps o de conexiones si utilizamos netstat.

Podemos decir que la tubería es una forma de redirección. Las herramientas de redirección pueden cambiar la fuente o el destino de los datos del proceso. La línea de comandos también nos ofrece otras formas de redirección. Aprender su funcionamiento no es algo muy complejo.

Entrada y salida de datos

Para entender el funcionamiento de la entrada y salido de datos, podemos decir utilizar de ejemplo el uso de la herramienta grep. Esta lee los datos desde el “standard input inpute” (stdin) y emite los resultados al “standard output device” (stdout). Los errores se envían a un tercer canal llamado “standard error device” (stderr)

Por norma general los datos para stdin se proporcionan desde el teclado y por defecto, tanto stdout como stderr, se envían al terminal conectado a nuestra línea de comandos o shell. De todos modos, podemos redirigir cualquier cualquiera de ellos. A modo de ejemplo podemos redirigir stdin para que lea los datos desde un fichero en vez del teclado, o bien redirigir stdout y stderr, de manera separada, para escribir los datos en otro lugar distinto de la ventana de la terminal. De esta forma podemos redirigir la salida stdout de un comando en la entrada stdin del siguiente.

Resumiendo:

  • STDIN es el dispositivo de entrada estandar, que por defecto es el teclado.
  • STDOUT es el dispositivo de salida estandar, que por defecto es la terminal de comandos o bien la pantalla.
  • STDERR es el dispositivo de salida de mensajes de error, también por defecto es la terminal de comandos o bien la pantalla.

La manera de utilizarlos (las tuberías y redirecciones) dependen la línea de comandos que utilicemos, aunque la mayoría soporten las operaciones más típicas:

  • < fichero_entrada redirige stdin para leer datos del fichero nombrado.
  • > fichero_salida redirige stdout, enviando los resultados de un comando o una tubería (pero no los errores) a un fichero. Si este fichero no existe, se crea; en cambio, si existe, su contenido se sobrescribe con los resultados.
  • >> fichero_salida es similar > pero añade stdout al fichero nombrado. Si el fichero no existe, se crea; sin embargo, si existe, son contenido se conserva y añade los resultados justo al final.
  • 2> fichero_salida crea un nuevo fichero que contiene el error estándar. Si el fichero especificado existe, se sobresescribe.
  • 2>> fichero_salida añade el error estándar al fichero existente. Si el fichero especificado no existe, lo crea.
  • >& fichero salida funciona como >, pero catura stdout y stderr en el fichero especificado, creando el fichero si es necesario, y sobrescribiendo el contenido si existía previamente.

Uso avanzado de las tuberías

La herramienta find es sin duda una de las más utilizadas, por lo menos desde el administrador de sistemas. Ya que facilita encontrar un archivo dado, cumpliendo con ciertos parámetros, de manera bastante rápida, dentro de un sistema de ficheros. Si no lo conocéis a fondo os hablé de él en esta entrada: 17 ejemplos prácticos del comando find en GNU Linux

Podemos utilizar las tuberías de la siguiente manera:

find / -type f -mtime +15 |xargs du -sh

De esta manera buscaremos desde la raíz del sistema de ficheros todos los archivos de más de 15 días; al utilizar una tubería la salida stdout del principio pasa por xargs. Esta cláusula es especial: arranca un comando, en este caso du y todo lo demás, hasta el final de la línea, una vez por cada fichero listado por find.

Redireccionamiento de entrada y salida en un mismo comando

También podemos utilizar la entrada (stdin) y salida (stdout) estandar en una misma línea:

sort < lista_de_la_compra.txt > lista_de_la_compra_ordenada.txt

En este caso el comando sort, mediante la entrada estandar (stdin) recibe los datos de la lista de la compra y los ordena; a su vez se utiliza la salida estandard (stdout) para enviar la lista ordenada a otro fichero.

Llamando a /dev/null

Tal y como hemos visto, prácticamente la mayoría de los comandos emiten salida de un tipo u otro. Estos comandos utilizan stdout y stderr para mostrar mensajes de progreso y error, en este orden. Si nos interesa eliminar este tipo de salidas, lo cual es muy útil, ya que pueden interferir estos mensajes, en el funcionamiento de la línea de comandos. Para evitar estos, debemos redirigir la salida a /dev/null, donde se borran de manera inmediata.

Como hemos dicho la redirigimos la salida a /dev/null no se mostrará nada. Sin embargo, si cometemos un error, los mensajes de error, los cuales son emitidos a la salida de error estándar, si se mostrarán. En cambio, si deseamos ignorar todos los mensajes, debemos utilizar el operador >&, así enviamos en stdout y stderr a la basura.

Los usos más habituales en este caso son:

  • comando > /dev/null 2>&1
  • ./guion.sh > /dev/null/2>&1
  • ./ejemplo.sh > /dev/null 2>&1

O bien, de manera similar:

  • comando &>/dev/null
  • job arg1 arg2 &>/dev/null
  • /ruta/al/guion argumento &>/dev/null

También se suele utilizar mucho en trabajos programados en cron y crontab:

@hourly /giones/backup/nfs.backup >/dev/null 2>&1

O bien:

@hourly /giones/backup/nfs.backup &>/dev/null

Como ya vimos, también podemos utilizar /dev/null para vaciar ficheros.

Y esto es todo, espero que estos pequeños apuntes os puedan de ser de utilidad en algún momento.

Fuentes consultadas

nixCraft – BASH Shell Redirect Output and Errors To /dev/null