🖇️
Apuntes LPIC-1
  • General
  • Ejercicios de utilidades
  • 1️Examen 101
    • Tema 101: Arquitectura del Sistema
    • Tema 102: Instalación de Linux y gestión de paquetes
    • Tema 103: Comandos GNU y Unix
      • 103.1 - Trabajar desde la línea de comandos
      • 103.2 - Procesar secuencias de texto usando filtros
        • Listado de texto plano
        • Ejercicios 103.2
      • 103.3 - Administración básica de archivos
      • 103.4 - Uso de secuencias de texto, tuberías y redireccionamientos
      • 103.5 - Crear, supervisar y matar procesos
        • 🚧Ejercicios 103.5
      • 103.6 Modificar la prioridad de ejecución de los procesos
      • 103.7 - Realizar búsquedas en archivos de texto usando expresiones regulares
      • 103.8 - Edición básica de archivos
    • Tema 104: Dispositivos, sistemas de archivos Linux y el estándar de jerarquía de archivos
    • Test prueba
  • 2️Examen 102
    • Tema 105: Shells y scripts
    • Tema 106: Interfaces de usuario y escritorios
    • Tema 107: Tareas administrativas
    • Tema 108: Servicios esenciales del sistema
    • Tema 109: Fundamentos de redes
    • Tema 110: Seguridad
Powered by GitBook
On this page
  • Objetivos del tema 105
  • 105.1 Personalizar y usar el entorno de shell
  • Contenidos
  • Iniciando una terminal
  • Ejecutando shells con su y sudo
  • Shell interactivo de inicio de sesión
  • Shell Interactivo sin inicio de sesión
  • Shell no Interactivo de inicio de sesión
  • Archivos fuentes
  • Variables
  • Variables locales o de Shell
  • Variables globales o de entorno
  • Ejecución de programa en entorno modificado
  • Creando Alias
  • Creando funciones
  • 105.2 Personalización y escritura de scripts sencillos
  • Contenidos
  1. Examen 102

Tema 105: Shells y scripts

Objetivos del tema 105

  • 105.1 Personalizar y usar el entorno de shell

  • 105.2 Personalización y escritura de scripts sencillos

105.1 Personalizar y usar el entorno de shell

Importancia

4

Descripción

El candidato debe ser capaz de personalizar el entorno de shell para adaptarlo a las necesidades de los usuarios así como de modificar perfiles globales y de usuario.

Áreas de conocimiento clave:

  • Establecer variables de entorno (e.g. PATH) al inicio de sesión o al generar un nuevo shell.

  • Escribir funciones en Bash para secuencias de comandos usadas con frecuencia.

  • Mantener el esqueleto de directorios para nuevas cuentas de usuario.

  • Establecer el directorio adecuado en la ruta de búsqueda de comandos.

Contenidos

El shell es posiblemente la herramienta más poderosa en un sistema operativo Linux y puede definirse como una interfaz entre usuario y kernel, tiene la función de Interpretar los comandos introducidos por el usuario, por lo tanto, los administradores de sistemas deben ser hábiles en su uso.

El Bourne Again Shell (Bash) es el shell de facto de la gran mayoría de las distribuciones de Linux. En el momento que el sistema operativo inicia, lo primero que el Bash (o cualquier otro shell) realiza, es ejecutar una serie de scripts de inicio que personalizan el entorno de sesión.

Existen varios scripts para todo el sistema operativo, así como también para usuarios específicos, en estos scripts podemos elegir las preferencias o configuraciones que mejor se adapten a las necesidades de nuestros usuarios en forma de variables, alias y funciones y la serie exacta de estos depende de un parámetro muy importante: El tipo de shell.

Iniciando una terminal

En un entorno de escritorio, podemos abrir una terminal o cambiar a una de las consolas del sistema fácilmente. Aquí tenemos que un nuevo shell es un pts cuando se abre desde un emulador de terminal en el GUI o una tty cuando se ejecuta desde una consola de sistema.

tty significa "teletypewritter"; pts significa "pseudo terminal slave". Para más información: man tty y man pts.

Como parte de las sesiones gráficas, los emuladores de terminales como gnome-terminal o konsole son muy amplios en características y fáciles de usar en comparación con las terminales de interfaz de usuario basadas en texto. A continuación, tienes algunos otros para hacerte una idea:

Usando las teclas Ctrl+Alt+F1-F6 podemos ir a los inicios de sesión de la consola que abren un shell de inicio de sesión interactivo basado en texto y la combinación de Ctrl+Alt+F7 llevará la sesión de vuelta al escritorio.

Después de iniciar sesión, escribe bash en una terminal para abrir un nuevo shell (técnicamente, este shell es un proceso hijo del shell actual). Al iniciar el proceso hijo de bash, podemos especificar varias opciones para definir qué tipo de shell queremos iniciar. Aquí hay algunas importantes a la hora invocarlo:

  • bash -l o bash --login -> Invocará un shell de inicio de sesión.

  • bash -i -> Invocará un shell interactivo.

  • bash --noprofile -> Con shell de inicio de sesión ignorará tanto el archivo de inicio de todo el sistema /etc/profile como los archivos de inicio a nivel de usuario ~/.bash_profile, ~/.bash_login y ~/.profile.

  • bash --norc -> Con shell interactivo ignorará tanto el archivo de inicio del sistema /etc/bash.bashrc como el archivo de inicio a nivel de usuario ~/.bashrc.

  • bash --rcfile -> Con shell interactivo tomará como el archivo de inicio ignorando a nivel de sistema etc/bash.bashrc y a nivel de usuario ~/.bashrc.

Ejecutando shells con su y sudo

A través del uso de estos dos programas (similares) podemos obtener tipos específicos de shells:

su cambia el ID de usuario o lo convierte en superusuario (root). Con este comando podemos invocar ambos shells, el de con inicio de sesión y sin inicio de sesión:

  • su - user2, su -l user2 o su --login user2 iniciará un shell de inicio de sesión interactivo como user2.

  • su user2 iniciará un shell interactivo y sin inicio de sesión como user2.

  • su - root o su - iniciará un shell de inicio de sesión interactivo como root.

  • su root o su iniciará un shell interactivo y sin inicio de sesión como root.

sudo por su lado, ejecuta comandos como otro usuario (incluyendo tambien el superusuario). Debido a que este comando se usa principalmente para obtener privilegios temporales de root, el usuario que lo use debe estar en el archivo ~/sudoers (aunque por cuestiones de seguridad no es recomendable). Para añadir usuarios a ~/sudoers necesitamos convertirnos en root y luego ejecutar:

sudo su
usermod -aG sudo user2 

Así como su, sudo nos permite invocar tanto los shells de inicio de sesión como los de no de inicio de sesión:

  • sudo su - user2, sudo su -l user2 o sudo su --login user2 iniciará un shell de inicio de sesión interactivo como user2.

  • sudo su user2 o sudo -u user2 -s iniciará un shell interactivo sin inicio de sesión como user2.

  • sudo su - root or sudo su - iniciará un shell de inicio de sesión interactivo como root.

  • sudo -i iniciará un shell de inicio de sesión interactivo como root.

  • sudo -i <some_command> iniciará un shell de inicio de sesión interactivo como root, ejecuta el comando y volverá al usuario original.

  • sudo su root or sudo su iniciará un shell interactivo sin inicio de sesión como root.

  • sudo -s or sudo -u root -s iniciará un shell sin inicio de sesión como root.

Cuando se usa su o sudo, es importante considerar el inicio de un nuevo shell y preguntarnos: ¿Necesitamos el entorno del usuario o no? Si es así, usaríamos las opciones que invocan las shells de inicio de sesión; si no, las que invocan sin inicio de sesión.

Para saber en qué tipo de shell estamos trabajando, podemos escribir:

 echo $0 
#Y dependiendo de la salida:
-bash o -su        #Inicio de sesión interactivo 
bash o /bin/bash   #Sin inicio de sesión interactivo
<name_of_script>   #Sin inicio de sesión no interactivo (scripts)  

También, para observar cuántos bash shells tenemos en ejecución en el sistema, podemos usar el comando:

ps aux | grep bash
#Podriamos ver algo así:
# user2 5270 0.1 0.1 25532 5664 pts/0 Ss 23:03 0:00 bash
# user2 5411 0.3 0.1 25608 5268 tty1 S+ 23:03 0:00 -bash
# user2 5452 0.0 0.0 16760  940 pts/0 S+ 23:04 0:00 grep --color=auto bash
  • Esto significa que el user2 ha entrado en una sesión de GUI (Sistema de Ventanas X o en ingles: X Window System) y ha abierto gnome-terminal, luego ha pulsado Ctrl+Alt+F1 para entrar en una sesión terminal con inicio de sesión interactivo detty (Mira como el último campo de cada línea es bash para el primero y -bash para el segundo). Finalmente, ha vuelto a la sesión del GUI presionando Ctrl+Alt+F7 y ha escrito el comando ps aux | grep bash. De esta manera, la salida muestra un shell interactivo sin inicio de sesión a través del emulador de terminal (pts/0) y un shell de inicio de sesión interactivo a través de la propia terminal basada en texto (tty1).

Shell interactivo de inicio de sesión

Primero de todo, para este shell, mencionar que los scripts de todo el sistema o globales se colocan en el directorio /etc/, mientras que los locales o de nivel de usuario (local) se encuentran en el directorio /home del usuario (~):

Nivel Global

  • /etc/profile -> el archivo .profile usado para todos los shell Bourne y shells compatibles (Incluido bash). A través de una serie de declaraciones if este archivo establece un número de variables como $PATH y $PS1, así como origen tanto del archivo /etc/bash.bashrc como los del directorio /etc/profile.d

  • /etc/profile.d/* -> Directorio que puede contener scripts que son ejecutados por /etc/profile.

Nivel Local (~)

  • ~/.bash_profile -> archivo específico de Bash utilizado para configurar el entorno del usuario. También puede ser usado para crear el ~/.bash_login y ~/.profile

  • ~/.bash_login -> este archivo (específicamente), sólo se ejecutará si no hay un archivo ~/.bash_profile.

  • ~/.profile -> Este archivo no es específico de Bash y se obtiene sólo si no existen ni ~/.bash_profile ni ~/.bash_login, que es lo que normalmente ocurre. Por lo tanto, el propósito principal de este es el de revisar si se está ejecutando un shell de Bash, y si fuese afirmativo, obtener ~/.bashrc (si existe). Normalmente establece la variable $PATH para que incluya el directorio privado del usuario ~/bin (si existe).

  • ~/.bash_logout -> Si existe, este archivo específico de Bash hace algunas operaciones de limpieza al salir del shell, lo cual puede ser conveniente en casos como los de las sesiones remotas.

Para probar a mostrar algunos de estos archivos en acción, vamos a modificar /etc/profile y /home/user2/.profile. Añadiremos a cada uno una línea que nos recuerde el archivo que se está ejecutando:

echo 'echo Hello from /etc/profile' >> /etc/profile 
echo 'echo Hello from ~/.profile' >> ~/.profile

Para probarlo, veamos qué pasa cuando user2 se conecta vía ssh desde otra máquina:

ssh user2@192.168.1.6
#Linux debian 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64

#Los programas incluidos en el sistema Debian GNU/Linux son software libre; los términos
#exactos de distribución de cada programa se describen en archivos individuales en
#/usr/share/doc/*/copyright.

#Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
#permitted by applicable law.
#Last login: Tue Nov 27 19:57:19 2018 from 192.168.1.10
#Hello from /etc/profile
#Hello from /home/user2/.profile

Como se observan en las dos últimas líneas, funcionó y nótese tres cosas:

  • El archivo global se ejecutó primero.

  • No había archivos .bash_profile o .bash_login en el directorio "home" de user2.

  • La tilde (~) se expandió a la ruta absoluta del archivo (/home/user2/.profile).

Shell Interactivo sin inicio de sesión

Nivel Global

  • /etc/bash.bashrc -> Este es el archivo .bashrc de todo el sistema para los shells interactivos bash. A través de su ejecución, bash se asegura de que se está ejecutando interactivamente, comprueba el tamaño de la ventana después de cada comando (actualizando los valores de LÍNEAS y COLUMNAS, si es necesario) y establece algunas variables.

Nivel Local

  • ~/.bashrc -> Además de llevar a cabo tareas similares a las descritas para /etc/bash.bashrc a nivel de usuario (como comprobar el tamaño de la ventana o si se está ejecutando de forma interactiva), este archivo específico de Bash suele establecer algunas variables de historial y origen ~/.bash_aliases (si existe). Aparte de eso, este archivo se utiliza normalmente para almacenar alias y funciones específicas de los usuarios. Asimismo, también vale la pena señalar que ~/.bashrc se lee si bash detecta que su es una conexión de red (como ssh).

Modifiquemos ahora /etc/bash.bashrc y /home/user2/.bashrc:

echo 'echo Hello from /etc/bash.bashrc' >> /etc/bash.bashrc
echo 'echo Hello from ~/.bashrc' >> /.bashrc 

#Esto ocurrirar cuando user2 comienza un nuevo shell: 
bash 
# Hello from /etc/bash.bashrc
# Hello from /home/user2/.bashrc

Shell no Interactivo de inicio de sesión

Un shell no interactivo con las opciones -l o --login es forzado a comportarse como un shell de inicio de sesión y así los archivos de inicio a ser ejecutados serán los mismos que los de los shells de inicio de sesión interactivos.

Para probarlo, escribamos un simple script y hagámoslo ejecutable. No incluiremos ningún shebangs porque invocaremos el ejecutable bash (/bin/bash con la opción de inicio de sesión) desde la línea de comandos:

  1. Creamos el script test.sh para probar que el script se ejecuta con éxito: echo "echo 'Hello from a script'" > test.sh

  2. Hacemos que nuestro script sea ejecutable: chmod +x ./test.sh

  3. Finalmente, invocamos a bash con la opción l para ejecutar el script: bash -l ./test.sh

  4. Esto da como resultado:

#Hello from /etc/profile
#Hello from /home/user2/.profile
#Hello from a script

¡Funciona! Antes de ejecutar el script, el login tuvo lugar y tanto el /etc/profile como el ~/.profile fueron ejecutados. Lo mismo ocurriria con una sesión de ssh.

Archivos fuentes

En las secciones anteriores hemos discutido que algunos scripts de inicio incluyen o ejecutan otros scripts, a este mecanismo se le llama "sourcing" y se explica en esta sección.

El punto (.) se encuentra normalmente en los archivos de inicio, en el archivo .profile de nuestro servidor de Debian podemos encontrar un ejemplo en el siguiente bloque:

# include .bashrc if it exists
  if [ -f "$HOME/.bashrc" ]; then
  . "$HOME/.bashrc"
  fi

Hemos observado cómo la ejecución de un script puede llevar a la de otro. Así la declaración if garantiza que el archivo $HOME/.bashrc — si existe (-f) — se obtendrá (es decir, se leerá y se ejecutará) en el inicio de sesión.

Además, podemos usar el . siempre que hayamos modificado un archivo de inicio y queramos hacer efectivos los cambios sin necesidad de reiniciar. Por ejemplo, vamos a agregar un alias a /.bashrc:

echo "alias hi='echo We salute you.'" >> ~/.bashrc

# Ahora, imprime la última línea de /.bashrc para comprobar que todo ha ido bien:
tail -n 1 !$ #Para ssh
tail -n 1 ~/.bashrc 
# alias hi='echo We salute you.' 

#Se ejecuta el archivo manuamente:
. /.bashrc

#Y vemos que funciona:
hi
# hi We salute you.

El comando source es un sinónimo de (.) así que para ejecutar /.bashrc también podemos hacerlo de esta manera:

source ~/.bashrc

SKEL

SKEL es por definición, el origen de los archivos de inicio de Shell, una variable cuyo valor es la ruta absoluta al directorio skel el cual, sirve como plantilla para la estructura del sistema de archivos de los principales directorios de los usuarios. Incluye los archivos que serán heredados por cualquier nueva cuenta de usuario que se cree (incluyendo, por supuesto, los archivos de configuración de los shells). El SKEL y otras variables relacionadas se almacenan en el /etc/adduser.conf, que es el archivo de configuración para adduser:

grep SKEL /etc/adduser.conf
# La variable SKEL especifica el directorio que contiene el usuario "skeletal"...
SKEL=/etc/skel
# Si SKEL_IGNORE_REGEX está configurado, adduser ignorará los archivos que coincidan con este.
SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"

#Lo encontraremos aquí y si hacemos un -a veremos los scripts de inicio de shells:
ls -a /etc/skel/

Una buena práctica es crear un directorio en /etc/skel para que todos los nuevos usuarios almacenen sus scripts personales:

#1- Como root nos movemos a /etc/skel:
sudo su 
cd /etc/skel/

#2- Listamos su contenido:
ls -a

#3- Creamos nuestro directorio y comprobamos que todo ha ido como se esperaba:
mkdir my_personal_scripts
ls -a

#4- Ahora borramos user2 junto con su directorio home:
deluser --remove-home user2

#5- Añadimos user2 de nuevo para que tenga un nuevo directorio principal:
adduser user2

#6- Finalmente, entramos como user2 y listamos todos los archivos en /home/user2 para comprobar el resultado:
su - user2
ls -a /home/user2
#Veremos: . .. .bash_history .bash_logout .bashrc my_personal_scripts .profile

Variables

Las variables son como una caja imaginaria en la que coloca temporalmente una información y al igual que los scripts de inicialización, Bash clasifica las variables como shell/local (las que se ubican sólo dentro de los límites del shell en el que fueron creadas) o entorno/global (las que son heredadas por shells y/o procesos hijos).

En Bash, dar un valor a un nombre se llama asignación de variables y es la forma en que creamos o establecemos las variables. Por otro lado, el proceso de acceder al valor contenido en el nombre se llama variable referenciada.

La sintaxis para la asignación de variables es: <variable_name>=<variable_value> . Ten en cuenta de no dejar espacios a ninguno de los lados, por ejemplo:

distro=zorinos 

#Para comprobar su valor usamos echo y la variable con $:
echo $distro
#Resultado: zorinos

El nombre de una variable puede contener letras (a-z,A-Z), números (0-9) y guiones bajos (_) pero no puede empezar con un numero ni puede contener espacios (ni siquiera usando comillas).

#SÍ:
distro=zorinos
DISTRO=zorinos
distro_1=zorinos
_distro=zorinos
my_distro=zorinos

#Pero NO:
1distro=zorinos
"my distro"=zorinos

Para los valores también hay una serie de normas a seguir, estas pueden contener cualquier carácter alfanumérico (a-z,A-Z,0-9) así como la mayoría de los caracteres (?,!,*,.,/, etc.) pero si deseas poner un espacio, deberá ir entre comillas (" " o ' ' ) lo mismo ocurre si queremos poner símbolos como los utilizados para la redirección (<,>) o el símbolo de "pipe" (|).

#Esto SÍ
distro=zorin12.4?

distro="zorin 12.4"
distro='zorin 12.4'
distro=">zorin"

Sin embargo, las comillas simples (' ') y dobles (" ") no siempre son intercambiables ya que según lo que hagamos con una variable (asignación o referencia), el uso de una u otra tiene implicaciones y dará resultados diferentes.

  • Las comillas simples toman todos los caracteres del valor de la variable LITERALMENTE.

  • Las comillas dobles permiten la sustitución de la variable por su valor.

Esto se ve muy bien con el siguiente ejemplo:

lizard=uromastyx

animal='My $lizard'
echo $animal
#Resultado: My $lizard

animal="My $lizard"
echo $animal
#Resultado: My uromastyx

Variables locales o de Shell

Las variables locales o de shell existen sólo en el shell en el que se crean (De hecho, por convención, las estas las escribiremos en minúsculas). Es el caso de las variables que hemos visto en la sección anterior. Estas — siendo una variable local — no serán heredadas por ningún proceso hijo generado desde el shell actual.

En ciertos scripts la inmutabilidad puede ser una característica interesante de las variables. Para ello, podemos crearlas en modo sólo lectura (readonly):

readonly reptile=tortoise 

#O bien a posterior:
reptile=tortoise 
readonly reptile

#Esto dará error al volver a asignar la variable
#Para listar todas las variables de sólo lectura en nuestra sesión actual, podemos escribir:
readonly
#ó
readonly -p

Un comando útil cuando se trata de variables locales es set. Este da salida a todas las variables y funciones de shell que se encuentran actualmente asignadas. Dado que pueden ser muchas líneas (¡pruébalo tú mismo!), se recomienda usarlo en combinación con un buscador como set | less

De la misma forma, para eliminar cualquier variable (ya sea local o global), usamos el comando unset seguido del nombre de la variable sin el $

Variables globales o de entorno

Existen variables globales o de entorno para el shell actual, así como para todos los procesos subsecuentes que se derivan de este (Por convención, las variables de entorno se escriben en mayúsculas) es el caso de $SHELL o de $PATH.

Para que una variable de shell local se convierta en una variable de entorno, se debe utilizar el comando export <nombre> (o tambien declare -x), de esta formas convertimos nuestra variable local en una variable de entorno para que los shells hijos puedan reconocerla y usarla. Para volverla local otra vez simplemente usamos export -n <nombre> .

El comando export por si mismo mostrará un listado de las variables globales aunque también podemos listarlo con export -p, env y printenv.

Es hora de revisar algunas de las variables de entorno más relevantes que se establecen en los archivos de configuración de Bash:

  • DISPLAY -> En relación con el servidor X. Un valor vacío (:0) para esta variable significa un servidor sin un sistema X WIndow, mientras que un número extra (como en mi.xserver:0:1) se referiría al número de pantalla (si existe más de uno).

  • HISTFILE -> El nombre del archivo que almacena todos los comandos a medida que se escriben. Por defecto este archivo se encuentra en ~/.bash_history y podemos verlo con el comando history.

  • HISTCONTROL -> Esta variable controla qué comandos se guardan en HISTFILE. Hay tres valores posibles:

    • ignorespace Los comandos que empiecen con un espacio no se guardarán.

    • ignoredups Un comando que es el mismo que el anterior no se guardará.

    • ignoreboth Los comandos que caen en cualquiera de las dos categorías anteriores no se guardarán.

  • HISTSIZE -> Establece el número de comandos que se almacenarán en la memoria mientras dure la sesión de shell.

  • HISTFILESIZE -> Establece el número de comandos que se guardarán en HISTFILE tanto al principio como al final de la sesión.

  • HOME -> La variable almacena la ruta absoluta del directorio principal del usuario y se establece cuando el usuario se conecta. Recuerda que ~ es equivalente a $HOME

  • HOSTNAME -> Variable que almacena nombre del computador en la red.

  • HOSTTYPE -> Almacena la arquitectura de la unidad central de procesamiento (CPU) del computador.

  • LANG -> Esta variable guarda la información de localización que utiliza el sistema.

  • MAIL -> Esta variable almacena el archivo en el que Bash revisa el correo electrónico.

  • MAILCHECK -> Esta variable almacena un valor numérico que indica en segundos la frecuencia con la que Bash comprueba si hay correo nuevo.

  • PATH -> Esta almacena la lista de directorios donde Bash busca los archivos ejecutables cuando se le indica que ejecute cualquier programa, en la mayoría de casos, esta variable se establece a través del archivo /etc/profile de todo el sistema. Si quisiéramos incluir la carpeta /usr/local/sbin en el $PATH para usuarios habituales, modificaremos la línea de ese archivo:

if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin"
#Añadimos al final, separado por ":" 
fi
export PATH

También podríamos hacerlo desde la linea de comandos así:

PATH=/usr/local/sbin:$PATH
#ó bien si queremos añadirlo al final de la linea:
PATH=$PATH:/usr/local/sbin
  • PS1 -> Esta variable almacena el valor del indicador Bash, también de /etc/profile, la sentencia if comprueba la identidad del usuario y en consecuencia brinda un indicador muy discreto ( # para root o $ para usuarios regulares):

if [ "`id -u`" -eq 0 ]; then
  PS1='# '
else
  PS1='$ '
fi

RECUERDA: El id de root es 0. Conviértete en root y puedes comprobarlo tú mismo con id -u.

  • SHELL -> Almacena la ruta absoluta del shell actual.

  • USER -> Almacena el nombre del usuario actual.

Ejecución de programa en entorno modificado

El comando env también puede ser usado para modificar el entorno del shell en el momento de la ejecución de un programa, si quisieramos abrir un shell lo más vacio posible de variables escribiriamos:

env -i bash 
#Ahora la mayoría de las variables de nuestro entorno han desaparecido.
#Podemos comprobarlo:
echo $USER
env
#Devolverá solo unos pocos

En este mismo topic, mas arriba, cuando hablamos de los shells no interactivos sin inicio de sesión, dijimos como los scripts no leen ningún archivo de inicio estándar sino que buscan el valor de la variable $BASH_ENV y lo usan como su archivo de inicio si existe, vamos a comprobarlo:

#1- Creamos nuestro propio archivo de inicio con el siguiente contenido:
cat .startup_script
    CROCODILIAN=caiman

#2- Escribimos un script Bash  con el siguiente contenido:
cat test_env.sh
    #!/bin/bash
    echo $CROCODILIAN
    
#3- Establecemos que el script test_env.sh sea ejecutable:
chmod +x test_env.sh

#4- Por último, usamos env para establecer la variable BASH_ENV en startup_script para test_env.sh:
env BASH_ENV=/home/user2/.startup_script ./test_env.sh
#lo cual nos devolverá "caiman"

#El comando env está implícito incluso si nos deshacemos de este:
BASH_ENV=/home/user2/.startup_script ./test_env.sh
  • Recuerda que usamos ./test_env.sh para ejecutar el script desde su propio directorio.

Creando Alias

Un alias es un nombre sustituto de otro(s) comando(s)y puede ejecutarse como un comando normal, pero en su lugar ejecuta otro comando según la definición de alias. Su sintaxis es muy sencilla:

# alias alias_name="command(s)"

# Por ejemplo:
alias oldshell=sh
#Este alias iniciará una instancia del shell original sh cuando el usuario digite oldshell en la terminal

#Otro ejemplo, alias nos permite "acortar" comandos:
alias ls='ls --color=auto'

#Tambien nos permite concatenar comandos con ";"
alias git_info='which git;git --version'

#Por si mismo mostrará un listado de alias:
alias
#Para borrarlos: 
unalias git-info


Entre algunas de las cosas que se pueden hacer incluye asignar y referenciar variables dentro de la declaración del alias, generar alias con nombres de comandos ya existentes (siempre tendrán prioridad los alias aunque puedes "escapar" de ellos escribiendo \ delante) o inlcuso poner un alias dentro de un alias.

Al igual que con las variables, para que nuestros alias ganen persistencia, debemos escribirlos en scripts de inicialización que se ejecuten al inicio como es ~/.bashrc. Probablemente encontrarás algunos alias allí (la mayoría de ellos comentados y listos para ser usados eliminando el # principal) e incluso como se puede leer en las últimas tres líneas, se nos ofrece la posibilidad de tener nuestro propio archivo dedicado a los alias ( ~/.bash_aliases ) y ser ejecutado por .bashrc con cada inicio del sistema así que podemos ir por esa opción, crear y editar dicho archivo para añadir los alias necesarios.

Después de añadir alias o funciones a cualquier archivo de script de inicio, debe ejecutar tales archivos con . o source para que los cambios surtan efecto si no quiere salir y volver a entrar o reiniciar el sistema.

Creando funciones

En comparación con los alias, las funciones son más programables y flexibles, especialmente cuando se trata de explotar todo el potencial de las variables incorporadas y los parámetros posicionales de Bash. Se trata de comandos que incluye la lógica a través de bloques o colecciones de otros comandos.

Hay dos sintaxis válidas para definir las funciones:

#Usando la palabra clave function seguida del nombre de la función y los comandos entre corchetes
function function_name {
command #1
command #2
command #n
}

#O bien, podemos omitir la palabra function y usar dos paréntesis () justo después del nombre de la función:
function_name() {
command #1 
command #2 
command #n 
}

Es común agregar funciones en archivos o scripts pero, también se puede escribir con cada comando en el shell prompt, en una línea diferente. Si decidimos saltarnos los ENTER y escribir una función en una sola línea, los comandos deben estar separados por punto y coma (también el último comando):

greet() { greeting="Hello world!"; echo $greeting; }

Ahora, para invocarla, tan solo debemos escribir su nombre en la terminal.

Bash trae un conjunto de variables especiales que son particularmente útiles para funciones y scripts, estas son especiales porque sólo pueden ser referenciadas — no asignadas:

  • $? -> Esta variable es usada para referenciar si el último comando usado ha dado error o no, un valor de 0 significa éxito y un valor distinto significara error.

  • $$ -> Muestra el PID del shell.

  • $! -> Muestra el PID del ultimo comando ejecutado de fondo (por defecto se ejecuta con & al final para que se hagan de fondo).

  • $# -> Muestra cuantos argumentos que se le pasan al comando.

  • $@, $* -> Se extienden a los argumentos pasados al comando.

  • $_ -> Se expande hasta el último parámetro o el nombre del script (¡revisa "man bash" para conocer más!).

  • $0 a $9 -> Parámetros posicionales, se usan para hacer una especie de matriz unitaria o como parámetros de orden y llamar a un listado siendo $0 siempre la del shell.

#por ejemplo, creamos la siguiente funcion:
$ special_vars() {
> echo $0
> echo $1
> echo $2
> echo $3
}

#Ahora le pasamos parametros:
special_vars debian ubuntu zorin

#Devolverá:
# -bash
# debian
# ubuntu
# zorin

De esta forma se pueden pasar parámetros para usarlos dentro de la función:

#home/user2/funed.sh :

#!/bin/bash
editors() {

editor=emacs

echo "The text editor of $USER is: $editor."
echo "Bash is not a $1 shell."
}
#Ahora le pasamos el parámetro:
editors tortoise

#Ejecutamos:
./funed.sh
    #The text editor of user2 is: emacs.
    #Bash is not a tortoise shell.
    
#El parámetro lo podemos incluir en el script o pasarselo por shell
Caso de ejemplo, script de información al usuario

Haciendo uso de la variable global PS1 vamos a crear una función llamada fyi (que se colocará en un script de inicio) que le dará al usuario la siguiente información:

  • Nombre del usuario

  • Directorio principal

  • Nombre del host

  • Tipo de sistema operativo

  • Buscar la ruta (PATH) de ejecutables

  • Directorio de correo

  • Con qué frecuencia se revisa el correo

  • ¿Cuántos shells tiene la sesión actual?

  • prompt (deberías modificarlo para que muestre @)

Para lograr ese propósito, hemos puesto la función en /home/user2/.bashrc

fyi() {
    echo -e "For your Information:\n
    Username: $USER
    Home directory: $HOME
    Host: $HOSTNAME
    Operating System: $OSTYPE
    Path for executable files: $PATH
    Your mail directory is $MAIL and is searched every $MAILCHECK seconds.
    The current level of your shell is: $SHLVL"
    PS1="\u@\h-\d " 
} 

fyi

Como se ha dicho antes, podemos agregar una función dentro de un alias:

alias great_editor='gr8_ed() { echo $1 is a great text editor; unset -f gr8_ed; }; gr8_ed' 

Vamos a desglosarlo:

  • Primero está la función en sí misma que, desglosada sería así:

gr8_ed() {
echo $1 is a great text editor
unset -f gr8_ed
}
  • El último comando de la función (unset -f gr8_ed) borra la función para que no permanezca en la sesión actual de bash después de que el alias sea llamado.

  • Por último, invocamos la propia función: gr8_ed.

Caso de ejemplo, saludo y advertencia a usuario

Vamos a probar otro ejemplo, pongámonos en que queremos comunicar dos cosas a user2 cada vez que se registre en el sistema que será, saludar y recomendar un editor de texto y advertirle sobre que la carpeta de videos esta añadiendo muchas cosas ($HOME/Video).

Para lograr ese propósito, hemos puesto las siguientes dos funciones en /home/user2/.bashrc.

La primera función (check_vids) hace el chequeo de los archivos .mkv y la advertencia:

check_vids() { 
    ls -1 ~/Video/*.mkv > /dev/null 2>&1 
    if [ "$?" = "0" ];then 
        echo -e "Recuerda, no deberias guardar mas de 5 vídeos en tu carpeta de vídeos.\nGracias." 
        else 
        echo -e "No tienes ningún video en tu carpeta. Puedes guardar hasta 5.\nGracias." 
        fi 
    }

Esto hace tres cosas:

  • Lista los archivos .mkv en ~/Video enviando la salida (y cualquier error 2>&1) al llamado bit-bucket (/dev/null).

  • Prueba la salida del comando anterior para el éxito (recuerda, si $?=0 es que ha tenido exito).

  • Dependiendo del resultado de la prueba, imprime uno de los dos mensajes.

Ahora vamos con la segunda función que es una versión modificada del ejemplo de más arriba:

editors() {
    editor=emacs
    echo "Hola, $USER!"
    echo "$editor es más que un editor de texto!"
    check_vids
    }

editors

Es importante observar dos cosas:

  • El último comando de editors invoca check_vids para que ambas funciones se encadenen: El saludo, el elogio, el chequeo y la advertencia se ejecutan en secuencia.

  • editors es el mismo punto de entrada a la secuencia de funciones, por lo que se invoca en la última línea (editors).

Ahora, entremos como user2 y probemos que funciona:

su - user2
    #Hola, user2! emacs es más que un editor de texto! 
    #Recuerda, no deberias guardar mas de 5 vídeos en tu carpeta de vídeos.
    #Gracias.


105.2 Personalización y escritura de scripts sencillos

Importancia

4

Descripción

El candidato debe ser capaz de personalizar scripts existentes o de escribir nuevos scripts sencillos en Bash.

Áreas de conocimiento clave:

  • Usar la sintaxis estándar sh (bucles, tests).

  • Usar la sustitución de comandos.

  • Evaluar correctamente el código de retorno de un comando en caso de éxito, fracaso o cualquier otra información que proporcione la salida del comando.

  • Ejecutar comandos en cadena.

  • Realizar envío de correo condicional al superusuario.

  • Seleccionar correctamente el intérprete del script mediante la línea inicial o shebang (#!).

  • Gestionar la ubicación, los propietarios, la ejecución y los permisos suid de los scripts.

Contenidos

PreviousTest pruebaNextTema 106: Interfaces de usuario y escritorios

Last updated 4 months ago

El tema de alias y variables lo veremos más a fondo en el siguiente

LD_LIBRARY_PATH -> Esta variable consiste en un conjunto de directorios separados por dos puntos donde las bibliotecas compartidas (shared libraries) son compartidas por los programas, se habló más de esto en el .

2️
topic 105.2
topic 102.3
Fuente: @dan_nanni