agosto 5, 2022
~ 14 MIN
La Terminal - Introducción
< Blog RSSLa Terminal - Introducción
Con este post arrancamos una nueva serie que estará centrada en la Terminal. Una de las características principales en el campo de la programación es la automatización de tareas. Existen multitud de herramientas que podemos usar para tales fines, siendo la Terminal una de las más interesantes a la hora de aumentar nuestra eficiencia ya sea en nuestro trabajo diario, investigación o estudios. En esta serie veremos muchas herramientas basadas en la Terminal, algunas de las cuales quizás ya conozcas, y cómo combinarlas para sacar el máximo partido. Esta serie está basada en el siguiente canal de Youtube: https://www.youtube.com/watch?v=Z56Jmr9Z34Q&list=PLyzOVJj3bHQuloKGG59rS43e29ro7I57J, por lo que te recomiendo que le eches un vistazo para obtener más información.
Conceptos Básicos
Una Terminal es la interfaz encargada de ejecutar e interactuar con una Shell, que a su vez interactua con el sistema operativo de un ordenador. Existen multitud de terminales y shells diferentes. A diferencia de las interfaces gráficas a las que estamos acostumbrados, en las que podemos usar el ratón para por ejemplo clickar en el icono de una aplicación si queremos abrirla, la Terminal es una interfaz basada en texto, en la que le diremos al ordenador lo que queremos hacer a base de comandos
. Todos los sistemas operativos ofrecen una forma u otra de Terminal por defecto. Por ejemplo, en MacOS puedes abrir el panel de búsqueda con CMD+Espacio
, escribir terminal
y al dar al Enter
abrirás la Terminal. De manera similar, en Windows puedes abrir el menú de búsqueda con la tecla Windows
y escribir terminal
para abrir la Terminal. Lo mismo en Ubuntu u otras distribuciones de Linux, en las que el uso de la Terminal es más habitual. Las terminales por defecto de Linux y MacOS ejecutan la shell de UNIX conocida como bash, por lo que su funcionalidad es prácticamente igual. En Windows, sin embargo, esto no es así y los comandos suelen ser diferentes, por lo que si quieres seguir los ejemplos en Windows te recomiendo que instales el subsistema de Linux para Windows WSL para poder usar los mismos comandos que iremos viendo a lo largo de la serie. De manera opcional, puedes instalar otras Terminales que te gusten más como por ejemplo iTerm en MacOS o tmux. Éstas permiten funcionalidades extra que te pueden ser útiles. De la misma manera, puedes instalar shells alternativas. En esta serie de posts usaremos oh my zsh, una shell basada en zsh. En la siguiente sección te dejo las instrucciones para instalarla en caso de que quieras que tu terminal se vea igual que la mía (es opcional).
Oh My Zsh (Opcional)
En esta sección aprenderás a instalar oh my zsh
y, a la vez, verás un primer ejemplo de uso de la terminal para descargar archivos, instalar programas y editar archivos de texto. Todo esto lo iremos viendo en detalle en los siguientes posts, así que no te asustes si te cuesta entenderlo a la primera :). Para instalar oh my zsh
abre la Terminal y ejecuta el siguiente comando (es posible que tengas que instalar curl
si no lo tienes ya instalado):
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Una vez instalado, te recomiendo instalar los siguientes plugins para añadir autocompletado y colores a la terminal que nos serán muy útiles. Para ello, de nuevo, ejecuta los siguientes comandos en la terminal (es posible que tengas que instalar git
si no lo tienes ya instalado):
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions
Una vez instalados los plugins, deberás añadirlos en el archivo ~/.zshrc
, el archivo de configuración de oh my zsh
. Para ello, puedes abre el archivo con el siguiente comando (es posible que tengas que instalar vim
si no lo tienes ya instalado):
vim ~/.zshrc
Baja hasta la línea en la que pone
plugins=(git)
y sustitúyela por
plugins=(
git
zsh-autosuggestions
zsh-syntax-highlighting
)
Para ello tendrás que presionar la tecla i
para entrar en el insert mode
, en la que podrás escribir. Una vez hecha la modificación presiona ESC
y luego guarda y cierra el archivo con la combinación de teclas :wq
.
Puedes ver un ejemplo de como tunear tu terminal en más detalle en este post.
En este primer ejemplo hemos usado curl
para descargar e instalar un programa, git
para descargar e instalar los plugins y vim
para editar el archivo de configuración. Si bien podríamos haber conseguido lo mismo usando el ratón y la interfaz gráfica del ordenador, la Terminal nos permite ejecutar estas operaciones de manera más rápida y lo que es más importante, automatizable. Como veremos más adelante es posible añadir todos estos pasos en un script
que nos permita ejecutar todas las operaciones de golpe lo cual es muy útil para, por ejemplo, configurar una terminal en un ordenador nuevo o servidor de manera rápida.
Ejecutando comandos
Una vez hayas abierto tu terminal ya puedes empezar a ejecutar comandos, o instrucciones para tu ordenador. Si has seguido la sección anterior (opcional) ya habrás visto un primer ejemplo de como hacer esto. En cualquier caso, para ejecutar un comando, simplemente tienes que abrir el terminal, escribir el nombre del comando y apretar ENTER
. El comando date
nos dará la fecha y hora.
Puedes ejecutar comandos en un notebook usando el prefijo
!
.
!date
Fri Aug 19 12:56:31 CEST 2022
Por defecto tu Terminal vendrá con muchos de los comandos que veremos instalados por defecto. De no ser así, tendrás que instalarlos. En función de tu sistema operativo, podrás instalarlos con
apt install <comando>
en Linux,brew install <comando>
en MacOS o de la manera indicada en Windows. Ante la duda, busca en google el comando en concreto y sigue las instrucciones de instalación para tu OS.
Un comando puede aceptar argumentos
, que modifican su comportamiento de alguna manera. El comando echo
nos devuelve lo que le pasemos como argumento.
Las palabras separados por espacios en blanco se interpretan como diferente argumentos, así que para usar un argumento con varias palabras tendrás que usar las comillas. Para saber dónde se encuentra localizado un programa en particular, usa el comando which
.
Variables de entorno
Tu pregunta ahora quizás sea: ¿y cómo sabe el ordenador lo que tiene que hacer cuándo se ejecuta un comando? Cuando instalamos un sistema operativo en un ordenador, éste viene acompañado de multitud de programas, muchos de ellos pensados para uso a través de la terminal. Estos programas están en el sistema de archivos del ordenador, y la shell se encarga de buscar estos programas y ejecutarlos cuando los invocamos a través de la terminal. Esto se consigue a través de una variable de entorno
. Lo cierto es que la shell es un entorno de programación en sí mismo, capaz de ejecutar loops, definir variables y funciones, de manera similar a como lo hacemos con lenguajes como Python
(de lo cual hablaremos en detalle en posts futuros). Las variables de entorno se definen cada vez que arrancamos la terminal e incluyen información tales como el nombre del usuario, el directorio raíz, etc. Una de estas variables de entorno es el PATH
, que incluye todas las localizaciones en las que la shell buscará programas.
Para referenciar una variable de entorno, usa el prefijo
$
.
Al ejecutar un comando, la shell buscará en todas las localizaciones definidas en el PATH
hasta encontrar un programa con el mismo nombre que el comando, entonces lo ejecutará. Quizás te ha pasado alguna vez que has intentado instalar un programa y luego al ejecutarlo no funciona. Tras buscar en google la respuesta que encuentras es que tienes que añadirlo al PATH
. Ahora ya sabes el porqué :)
En futuros posts veremos como podemos definir y usar nuestras propias variables de entorno.
Paths
Un path, o ruta, indica la localización de un archivo en el ordenador. En Windows, cada partición de disco duro de nuestro ordenador tiene su propia raíz (por ejemplo C:
o D:
) mientras que en MacOS y Linux todas las particiones tienen la misma raíz, /
. A partir de aquí, podemos localizar un archivo con su ruta navegando por las diferentes "carpetas", o directorios, separadas por /
en MacOS y Linux o \
en Windows. Por ejemplo, en MacOS un archivo localizado en tu escritorio tendrá el siguiente path:
/Users/<username>/Desktop/<filename>
donde <username>
será tu nombre de usuario y <filename>
el nombre del archivo. A esto se le llama path absoluto, ya que indica la localización del archivo desde la raíz. Por contra, un path relativo indica la localización de un archivo desde una localización diferente. Por ejemplo, si nos encontramos en el directorio home del usuario, la localizaión relativa del mismo archivo anterior sería
Desktop/<filename>
Date cuenta que el path relativo no es
/Desktop/<filename>
ya que esto sería un path absoluto !
Puedes conocer el path en el que te encuentres en cualquier momento con el comando pwd
.
El directorio home suele estar asignado al
alias
:~
. En la configuración deoh my zsh
recomendada siempre verás en qué directorio te encuentras en la terminal.
También puedes ejecutar un programa haciendo referencia a su path absoluto en el sistema de archivos, por ejemplo, en mi caso, /Users/sensio/miniforge3/bin/python
ejecutará directamente el interpretador de Python sin necesidad de buscarlo en el PATH
.
Navegando el sistema de archivos
Puedes moverte entre los diferentes directorios usando el comando cd
seguido el path (relativo o absoluto) al que te quieras mover.
También puedes moverte al directorio anterior usando cd ..
..
es unalias
para el directorio anterior, mientras que.
lo es para el directorio actual.
Mientras que cd -
te devolverá al directorio anterior, útil para cambiar entre dos directorios.
Cuando navegues por el sistema de archivo es fácil perderse o no saber qué directorios hay a tu alrededor, para ello puedes usar TAB
para mostrar sugerencias así como para autocompletado. Por otro lado, puedes usar el comando ls
para listar los archivos y directorios en el directorio en el que te encuentres.
Puedes pasar como argumento el directorio del que quieras listar archivos, por ejemplo ls ..
para listar los archivos del directorio anterior, ls /
para listar los archivos en home, etc. Una argumento muy usado es -l
, ya que nos dará información extra sobre los archivos tales como su tamaño, permisos, etc.
La primera columna nos dice quién tiene permisos para leer (read, r
), escribir (write, w
) y ejecutar (execute, x
) un archivo o directorio. Puedes jugar con estos permisos para restringir acceso a ciertas partes del sistema de archivos o la ejecución de programas a usuarios concretos. Podemos listar todos los subdirectorios de manera recursiva usando ls -R
, aunque una mejor forma de hacerlo es con el comando tree
.
Para cambiar el nombre o localización de un archivo, puedes usar el comando mv
.
Para copiar un archivo usa el comando cp
. Puedes copiar un directorio entero usando cp -r
.
Y para eliminar un archivo, usa el comando rm
o rm -r
para eliminar un directorio y todo su contenido.
Cuando elimines un archivo o directorio con
rm
no lo podrás recuperar (no hay una papelera de reciclaje de la que recuperarlo), por lo que úsalo con cuidado!
Puedes crear archivo con el comando touch
y directorios con el comando mkdir
, seguidos del nombre que quieras darle.
Encontrando archivos
Una de las principales tareas que podemos querer llevar a cabo es la de encontrar archivos en nuestro ordenador. Para ello, podemos usar el comando find
. En el siguiente ejemplo, buscaremos todos los archivos en el directorio en el que nos encontramos con el nombre hola
.
En el siguiente ejemplo, buscaremos todos los scripts de Python
en todos los subdirectorios.
El comando find
nos ofrece mucha versatilidad, por ejemplo podemos encontrar todos aquellos archivos que hayan sido modificados en el último día de la siguiente manera
Y una vez encontrados los archivos en los que estamos interesados, podemos ejecutar alguna acción sobre ellos, por ejemplo, eliminarlos.
Alternativamente, podemos usar el comando
locate
para encontrar en nuestro sistema todos los directorios o archivos con un nombre determinado.
En ocasiones no querremos encontrar archivos por su nombre, si no por su contenido. Para ello tenemos a nuestra disposición el comando grep
.
Este comando es muy útil para encontrar aquellos archivos en los que sabemos que tenemos una línea de código en particular pero no recordamos dónde exactamente.
Una alretnativa a grep
es ripgrep
, que además nos ofrecerá algunas ventajas como saber en qué línea del archivo se encuentra lo que buscamos, colores, etc.
Combinando programas
Hemos visto los conceptos básicos de la Terminal y algunos ejemplos de comandos que podemos ejecutar para movernos por nuestro sistema de archivos. Si bien ejecutar estos programas por separado es muy útil, hacerlo en combinación nos aportará una mayor funcionalidad. Para ello usaremos el concepto de streams. Un programa suele tener, como mínimo, un input stream, o stream de entrada, y un output stream, o stream de salida. Como podrás imaginar, estos streams pueden combinarse usando la salida de un programa como entrada a otro. Para ello usamos los símbolos <
y >
para redirigir la entrada y salida de un programa respectivamente. En el siguiente ejemplo usamos la salida del programa echo
como entrada para crear un nuevo archivo.
Puedes usar el comando
cat
para ver en la terminal el contenido de un archivo.
Por defecto, redirigir la salida de un programa con >
sobreescribirá cualquier contenido existente. Podemos usar >>
para concatenar la salida a cualquier contenido que ya exista. El siguiente ejemplo copia el contenido de un archivo a otro sin usar el comando cp
, utilizando los streams.
Otra manera que tenemos de combinar programas es usando el símbolo |
, llamado pipe. Esto cogerá la salida del programa de la izquierda y lo usará de entrada para el programa de la derecha. El siguiente ejemplo muestra las últimas 3 líneas del resultado de aplicar el comando ls -la
.
Puedes usar el comando
tail
para mostrar en la terminal las últimas líneas de un archivo, o en el ejemplo anterior, la salida de otra programa.
Por supuesto, podemos combinarlo con los streams para, por ejemplo, guardar el resultado en un archivo.
Es importante remarcar que estos programas no han sido programados específicamente para interactuar entre ellos, lo único que saben es trabajar con entradas y salidas. Somos nosotros los que redirigimos estas entradas y salidas para conseguir el efecto deseado.
Algunos comandos esperan que su entrada sea un archivo, por lo que es interesante poder asignar la salida de un comando a un archivo temporal que pueda ser consumido por otro programa. El siguiente ejemplo concatenará los archivos de un directorio y su padre.
Utilidades
Existe un comando especial man
al cual le puedes pasar como argumento otro programa y te devolverá su manual, la lista de instrucciones con todo lo que hace, los argumentos que acepta, etc. Muy útil si no recuerdas bien el funcionamiento de algún programa. Por ejemplo, man ls
abrirá el manual del programa ls
. Para cerrar el manual, presiona q
.
Puedes usar el comando clear
para limpiar la terminal.
De los diferentes usuarios que puede tener un ordenador, el usuario root es especial ya que puede hacer lo que quiera sin restricciones. No es habitual trabajar con este usuario, pero en ocasiones es necesario para hacer algunas operaciones concretas. Para poder ejecutar comandos bajo este usuario, podemos usar el programa sudo
seguido del comando que queramos usar.
Puedes recuperar comandos ejecutados anteriormente usando la flecha hacia arriba, o alternativamente usando CTRL+R
para filtrar los comandos usados. Puedes ver una lista de los comandos usados con el comando history
.
Resumen
En este primer post de la serie hemos introducido los concepts básicos para trabajar con la Terminal. Hemos visto cómo configurar oh my zsh
como shell y ejectuar diferentes comandos con sus argumentos. Hemos introducido el concepto de variables de entorno y paths. Hemos aprendido a navegar el sistema de archivos con comandos como cd
o ls
, encontrar archivos con find
o grep
y a combinar las salidas y entradas de programas para llevar a cabo tareas más interesantes. En posts futuros aprenderemos a automatizar tareas, manejar grandes volúmenes de datos e incluso crear programas para ejecutarlos en la Terminal.