agosto 5, 2022

~ 14 MIN

La Terminal - Introducción

< Blog RSS

Open In Colab

La 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.

date

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.

echo

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.

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.

path

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.

pwd

El directorio home suele estar asignado al alias: ~. En la configuración de oh 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.

cd

También puedes moverte al directorio anterior usando cd ..

.. es un alias para el directorio anterior, mientras que . lo es para el directorio actual.

cd3

Mientras que cd - te devolverá al directorio anterior, útil para cambiar entre dos directorios.

cd4

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.

ls

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.

ls2

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.

tree

Para cambiar el nombre o localización de un archivo, puedes usar el comando mv.

mv

Para copiar un archivo usa el comando cp. Puedes copiar un directorio entero usando cp -r.

cp

Y para eliminar un archivo, usa el comando rm o rm -r para eliminar un directorio y todo su contenido.

rm

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.

mkdir

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.

find1

En el siguiente ejemplo, buscaremos todos los scripts de Python en todos los subdirectorios.

find2

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

find3

Y una vez encontrados los archivos en los que estamos interesados, podemos ejecutar alguna acción sobre ellos, por ejemplo, eliminarlos.

find4

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.

grep1

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.

grep2

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.

grep3

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.

stream2

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.

stream3

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.

pipe1

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.

pipe2

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.

otros1

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.

< Blog RSS