Este es uno de los capítulos del tutorial El terminal. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.
Ya comenté en el capítulo 2 del tutorial sobre gestionar archivos, en Linux todo son archivos. En este sentido la pantalla y el teclado, son también dos archivos. ¿Como?, lo que has leído, tanto la pantalla como el teclado son dos archivos. Y te preguntarás, seguro que ¿porque te cuento esto?. Pues porque en este capítulo del tutorial vas a trabajar sobre estos dos archivos. Lo que vas a hacer es redirigir lo que se muestra por pantalla a otro sitio. Pero no solo esto, sino que también, en lugar de tomar lo que entra directamente por el teclado, vas a tomar lo que proviene de otro archivo. En definitiva vas a redirigir entrada y salida.
Pero, esto no es lo único que puedes hacer, también puedes encadenar la ejecución de comandos. ¿Encadenar ejecuciones?. De nuevo estoy hablando de redirigir la salida de un comando a otro comando, y luego a otro, y así sucesivamente. Es lo que se conoce como tuberías.
Redirigir entrada y salida
Con lo que te he comentado en la introducción, ya te puedes hacer una idea del potencial de redirigir entrada y salida. Es una buena manera de utilizar determinadas herramientas sin necesidad de utilizar archivos de almacenamiento intermedio.
Por ejemplo,La ejecución de algunos comandos en el terminal da como resultado un texto. Por ejemplo, al ejecutar ls
, el resultado es un texto que contiene el listado de archivos y directorios. Normalmente esto lo se muestra por pantalla, es decir, que la salida se dirige a la pantalla. Sin embargo, ¿que sucede si quieres guardar este listado? La solución es redirigir la salida del comando, en lugar de a la pantalla a un archivo, y de esta manera guardarlo.
Sobre entrada y salida
Cualquier comando que se ejecuta puede generar dos tipos de salida,
- un resultado. Es decir, aquello para lo que está pensado la herramienta en cuestión. En el caso de
ls
, que he comentado anteriormente, el resultado es el listado de archivos. - un estado. El estado se refiere a si la ejecución ha sido correcta. En caso de que la ejecución no haya sido correcta devolverá un mensaje de error para informar al usuario de los detalles de la ejecución.
En Linux existen tres tipos de archivos por defecto,
stdin
ó0
. Está conectado con el teclado.stdout
ó1
. Este archivo está conectado con la pantalla.stderr
ó2
. Cuando se produce un error, este se envía a este archivo, que también está conectado con la pantalla.
Redirigir entrada y salida te permite modificar tanto la entrada como la salida. Si normalmente introduces información desde el teclado, stdin
, podemos hacer por que entre desde otro archivo, por ejemplo. Igualmente puedes proceder con la salida, tal y como he comentado anteriormente.
Como redirigir entrada y salida
Redirigir salida
¿Como se puede redirigir entrada y salida estándar? Para esto tienes dos operadores de redirección, >
y <
. Así, por ejemplo, para guardar el resultado de ls
en un archivo, tan solo tienes que ejecutar el siguiente comando,
ls > salida.txt
De esta manera tan sencilla e intuitiva, estás guardando el resultado de listar archivos y directorios en un fichero.
Si quieres ver el resultado de la ejecución puedes ejecutar el comando cat salida.txt
.
Esto es equivalente a ejecutar ls 1>salida.txt
. Aquí estoy indicando que redirijo la salida estandar stdout
o 1
al archivo salida.txt
.
Si este arhivo ya existe, lo que va a suceder es que lo vas a reemplazar con el resultado de la ejecución de esta instrucción.
Añadir contenido a la salida
¿Como hacer para añadir contenido a un archivo? En este caso utilizarás el operador >>
. Así, por ejemplo cada vez que ejecutes ls >> salida.txt
, el resultado se añadirá al archivo existente.
Redirigir los errores
Para redirigir la salida de error de un comando, es necesario especificar el número del archivo de error. Así anteriormente, te he dicho que puedes ejecutar opcionalmente ls 1>salida.txt
. Para el caso del error, esto no es opcional. En este caso debes ejecutar ls 2>error.log
.
Por ejemplo, puedes probar con ls -l /root 2>error.log
, y verás el resultado. Igual que antes puedes ejecutar cat error.log
.
Redirigir salida y errores
Hasta el momento te he indicado como puedes redireccionar, o bien la salida estándar o bien los errores. ¿Como puedes redireccionar los dos a una misma salida?
Es posible redirigir tanto la salida como los errores a un mismo archivo. Para esto, es necesario utilizar los números que definen cada una de las salidas estándar. Para esto, tienes dos opciones,
ls >salida.txt 2>&1
. Consalida.txt
, indica que el resultado va al archivosalida.txt
, como has visto anteriormente. Y con2>&1
indicas que los errores se redirigen a la salida estándar, a1
. Como1
está redirigido a su vez asalida.txt
, ya lo tienes.ls &>salida.txt
. Esta segunda forma es mucho mas simple aunque menos intuitiva que la primera. Aquí también es posible añadir contenido, en lugar de reemplazar. Para ellols &>>salida.txt
.
Redirigir la entrada estándar
La mayoría de los comandos reciben su entrada desde la entrada estándar, que por defecto está conectada al teclado, como has visto anteriormente.
Para utilizar un archivo como entrada, en lugar de la entrada estándar, tienes que utilizar el operador <
. Prueba con cat < salida.txt
.
Redirigir entrada y salida estándar
Ahora ya puedes combinar tanto entrada como salida en una misma línea de comando. Esto, quizá no resulte tan intuitivo como lo que has visto anteriormente, al menos a mi así me resulta.
Por ejemplo, puedes utilizar el comando rev
para darle la vuelta al contenido de una archivo de texto. Así por ejemplo, en el caso de que tengas el archivo hola.txt
, que contenga hola
, y utilices rev hola.txt
te devolvéra por pantalla aloh
.
Ahora vas a redirigir entrada y salida. La entrada será hola.txt
y la salida será hola_al_reves.txt
. Así la línea de comando será,
rev < hola.txt > hola_al_reves.txt
Igualmente puedes añadir contenido en lugar de reemplazar,
rev < hola.txt >> hola_al_reves.txt
Tuberías ó encadenar comandos
Una interesante opción que te ofrece Linux es la posibilidad de encadenar comandos. De esta forma la salida de un comando resulta ser la entrada del siguiente. Esto es muy interesante, en tanto en cuanto, obviarás tener que guardar resultados intermedios en archivos.
Por ejemplo si quieres mostrar el listado de archivos de un directorio, pero con el texto al revés, ejecutarás la siguiente orden,
ls | rev
De esta sencilla manera, la salida de ls
resulta ser la entrada de rev
. Si además quieres guardarlo en un archivo,
ls | rev > texto_al_reves.txt
Y si quieres añadirlo, sin que borre el contenido existente,
ls | rev >> texto_al_reves.txt
Algunas herramientas útiles
Aunque lo verás en un capítulo posterior, a continuación, puedes encontrar algunos comandos o herramientas que que de seguro te serán de utilidad para utilizarlos en conjunción con tuberías.
head
. Extrae las primeras líneas de un archivo. Por ejemplo,head -1
sacará la primera línea del archivo`.tail
. Saca las últimas líneas de un archivo. Por ejemplo,tail -1
te sacará la última línea.cut
. Imprime parte de una línea de un archivo a una salida estándar. Por ejemplo,cut -d" " -f3
extraerá el campo 3 de la línea, donde los campos están separados por espacios.
Vamos allá, un ejemplo completo, ls -lah
. El resultado podría ser el siguiente,
total 32K
drwxrwxr-x 2 lorenzo lorenzo 4,0K mar 11 09:17 .
drwx------ 42 lorenzo lorenzo 4,0K dic 9 07:47 ..
-rw-rw-r-- 1 lorenzo lorenzo 150,0K mar 11 08:56 10.txt
Si quieres conocer el peso del archivo 10.txt
, puedes ejecutar lo siguiente,
ls -lah | tail -1 | cut -d" " -f6
El resultado 150K
.
Esto solo es para que te hagas una idea de las posibilidades que te ofrece redirigir entrada y salida en conjunción con algunos comandos. En un capítulo posterior te mostraré algunos comandos mas que te darán un importante abanico de posibilidades para trabajar con el terminal.
Más información,
Hola, Saludos desde Venezuela, ya te había escrito, espero que algún día puedas ver lo que he logrado con lo que me has enseñado.
Acà mi humilde contribución:
creo que falta el comando que permite ver en pantalla la salida del script y a la vez guardar la salida y el error en un archivo
#!/bin/bash
{
somecommand
somecommand2
somecommand3
} 2>&1 | tee /ruta_al_log/logfile.txt
Pregunta : Porque esto funciona
for file in *.pdf; do pdftotext -layout «$file» ->> salida.txt; done
y esto no :
for file in *.pdf; do pdftotext -layout «$file» >> salida.txt; done
1º ‘->>’ # Si funciona
2º ‘>>’ # No funciona