Apuntes mientras aprendo sobre software y computadoras.

Linux

Cómo convertir código de Bash en comandos personalizados

En este apunte rápido voy a estar revisando cómo agregar comandos personalizados en Bash para una mejor experiencia de uso.

La idea es la siguiente: tengo un script escrito en Bash y me interesa poder utilizarlo como un comandó mas. Mi objetivo es entender cómo hacer eso.

Antes de empezar: este texto es parte de mi “Guía básica para aprender a programar en Bash.” Se trata de mi diario de aprendizaje, en el que voy creando apuntes para entender mejor las cosas que estoy estudiando de manera autodidacta.

Planteando el problema:

Tengo un programa llamado “frase.sh”, y el contenido de este programa es el siguiente:

#!/bin/bash
echo "Este texto es un borrador"

El programa “frase.sh” se encuentra en el directorio “home”, dentro de la carpeta “ejemplo”. Puedo darme cuenta de eso con el comando “ls”:

gus@apunte:~/ejemplo$ ls
frase.sh

Ahora bien, lo primero que tengo que hacer si quiero invocar este programa esa darle permiso de ejecución.

chmod +rx frase.sh

Sin embargo… ¿Puedo ejecutar este programa desde cualquier lugar?

En un principio este código solamente puede ejecutarse si el directorio de trabajo en la terminal coincide con el directorio donde el programa esta guardado.

En mi ejemplo, “frase.sh” solamente puede invocarse cuando la terminal esta abierta en la carpeta ejemplo”.

Y lo puedo hacer escribiendo “./frase.sh”, en el directorio en el que el programa se encuentra, de la siguiente forma:

gus@apunte:~/ejemplo$ ./frase.sh
Este texto es un borrador

Tengo que recordar que el signo “$” indica que me encuentro posicionado en ese directorio.

El problema es que aunque el programa esta funcionando, es poco práctico poder utilizarlo solamente de esta forma.

Para compararlo con un script del sistema, puedo utilizar el comando “date” desde cualquier directorio. No importa en que directorio me encuentre, si escribo “date” recibo por respuesta la fecha y hora en la terminal.

En contraste si escribo “frase.sh” en otro directorio que no sea “/home/ejemplo”, recibo un error. Me dice que el comando no existe.

gus@apunte:~$ ./frase.sh
bash: ./frase.sh: No such file or directory

Existe una forma rápida de resolver esto, pero es una forma de poca ayuda en el largo plazo. Puedo escribir todo el camino al directorio donde se aloja el programa.

Digamos que al saber que mi programa se encuentra en la carpeta “ejemplo”, puedo invocarlo al escribir:

~/ejemplo/frase.sh
Este texto es un borrador

Si escribo todo el camino al programa puedo ejecutar el script desde cualquier directorio. Pero es una solución difícil de recordar y sin dudas mucho menos concreta que escribir solamente algo como “date”.

Y puede volverse más difícil si el script se encuentra dentro de varias carpetas.

Pero hay un modo más fácil de hacerlo, y es el que voy a detallar a continuación.

¿Qué busco ahora? Básicamente quiero poder ejecutar estos nuevos programas desde cualquier directorio, del mismo modo que hago con los otros comandos del sistema. Eso sin tener que aclarar cada vez que lo hago el camino al directorio donde se encuentra el código.

Cómo agregar nuevos comandos en Linux

¿Qué es el command path?

Command Path (o el “camino hacia los comandos”, si me piden mi propia traducción) es una variable de entorno del sistema.

Se trata de un archivo de texto que contiene una lista, y que le informa al sistema en que directorios tiene que buscar comandos que se pueden ejecutar.

Cuando invoco un comando, la shell busca ese comando en los distintos directorios definidos en el Command Path. Si el comando esta en uno de esos directorios, la shell puede usarlo.

Por otra parte, si el comando no aparece en ningún lado dentro de la lista, la terminal devuelve un error del estilo “comando no encontrado”.

El beneficio de añadir un script al Command Path es que entonces nuestro programa va a poder ser encontrado desde cualquier directorio, del mismo modo que un comando regular.

Puedo encontrar esta lista desde la terminal con:

echo $PATH

Lo que aparece en la pantalla es una serie de directorios incluidos dentro del archivo path, separados cada uno por dos puntos (:).

De este modo:

/home/gus/.local/bin:/usr/local/bin:/usr/sbin:/usr/bin:

Cuando invoco un comando, el sistema observa en cada una de estas (por ahora cuatro) carpetas y si lo encuentra pasa a ejecutarlo.

Esta búsqueda comienza por el primer directorio (de izquierda a derecha) hasta llegar al último. No importa si hay más de un comando con el mismo nombre en más de una carpeta, el sistema siempre ejecuta el primero que encuentra siguiendo ese orden.

Solución 1: mover el programa

La solución mas sencilla la encuentro si agrego mi programa en alguno de los directorios que ya existían señalados en el Command Path.

Si quiero que el comando sea accesible para otras cuentas del sistema puedo usar el directorio “/usr/local/bin”.

Y si necesito que el programa sea solamente invocado por la cuenta root, necesito guardar el programa en el directorio “/usr/local/sbin”.

Pero en mi caso particular puedo agregar “frase.sh” en el directorio “/home/gus/.local/bin” que ya se encuentra dentro del camino de búsqueda de comandos para el sistema. Este directorio no es global, y el nuevo comando va a aplicar solamente a mi cuenta.

Y no tengo que olvidar darle al programa un permiso de ejecución para que funcione.

chmod +rx frase.sh

Entonces, luego de mover el programa a esa carpeta, ya puedo invocar mi programa sin importar en que directorio se encuentre abierta la terminal:

gus@apunte:~$ frase.sh
El ejemplo funciona

¿Es necesario guardar el script de bash con la extensión “.sh”?

Por lo que pude notar, en Linux no es necesario agregar la extensión “.sh” en el archivo del programa para que el sistema lo entienda como lo entienda como ejecutable.

Entendido de esa forma, puedo nombrar mi programa como “frase”, sin la extensión, para que escribirlo en la terminal se vuelva todavía más sencillo:

gus@apunte:~$ frase
El ejemplo funciona

Solución 2: Modificar el Command Path

Bien, tengo mi directorio ejemplo. En esa carpeta guardo los scripts que voy creando mientras escribo estos apuntes y ahí se encuentra el programa que quiero ejecutar ahora.

Tal vez no es la mejor idea, pero puedo agregar este directorio “ejemplos” dentro del command path.

Para editar el command path, tengo que dirigirme primero a mí directorio personal (en mi ejemplo eso es “/Home/gus”). Allí voy a encontrar un archivo llamado “.profile” que se encuentra oculto en un primer momento.

Para ver ese archivo tengo que hacer click con el botón derecho del mouse dentro de la carpeta y activar “mostrar archivos ocultos” (Show Hidden Files).

Para modificar “.profile” es necesario abrirlo con un editor de texto sin formato. Puedo editarlo también directamente desde la terminal, usando un programa como Nano.

Ahora tengo que ir hasta el final del documento. Voy a actualizarlo agregando el camino al nuevo directorio, antecedido de:

export PATH=$PATH:/home/directorio

En mi caso este camino queda como:

export PATH=$PATH:/home/gus/ejemplo

La idea es poner esa linea de texto al final del documento. Y listo, ya puedo guardarlo.

Para que el cambio tenga efecto es necesario reiniciar el sistema. También puedo utilizar el comando source para que el System Path vuelva a ser leído/actualizado, haciendo que la nueva modificación tome efecto.

Entonces, en lugar de reiniciar abro una nueva terminal y escribo:

source ~/.profile

Ahora cuando utilizo el comando

echo $PATH

Voy a poder notar que la modificación tuvo efecto, y la nueva carpeta anexada aparece al final de la lista.

Lo mejor de añadir un nuevo camino al final del documento es que, como esta lista es leída en orden, voy a evitar cometer el error de adelantarme a una dirección o comando ya existente.

Del mismo modo, lo mejor es que la carpeta y los programas no tengan nombres que sean iguales a comandos ya usados en el sistema.

Pero si algo fue mal y quiero ver cómo era el command path en sus valores originales, puedo utilizar el comando:

source /etc/environment

Ademas ese último comando va a restaurar mi terminal actual a los valores originales de command path, al menos hasta que vuelva a cerrarla. Si neceisto eliminar este nuevo directorio, simplemente abro de nuevo el archivo “.profile” y elimino la linea que puse antes.

Y si quiero conocer el camino al directorio de un comando en particular puedo hacerlo con el comando “which” de la siguiente forma:

which nombredelcomando

Conclusión:

Con esto termino el apunte para entender cómo convertir código de Bash en comandos personalizados.

Esta es la versión expandida y corregida de un antiguo apunte que había escrito. Espero que esta nueva versión sea mejor que la anterior.

Si encontrás algún error en el texto o te parece que puedo mejorarlo, me gustaría leer tus comentarios. También se puede encontrar mi correo electrónico en la sección de contactos.

La seguimos en el próximo apunte.

Leave a Reply