En la parte 1 de esta serie recordamos sobre como implementar un:
Y en otras anteriores, nos empapamos de las mejores practicas a seguir a la hora de crear un excelente Script de Shell en Bash para Linux, y muy específicamente en cuanto a diseñar un Shebang y un BSM (Bash Strict Mode / Modo Bash Estricto).
Mejores practicas para crear un Script de Shell en GNU/Linux – Parte 1
Mejores practicas para crear un Script de Shell en GNU/Linux – Parte 2
En esta entrada veremos como implementar un Modulo de Variables de Entorno para un Script de Shell en Bash para Linux, tomando como ejemplo uno de mis programas (aplicaciones) hechos en un Script de Shell llamado Linux Post Install – Script Bicentenario 8.0, pero antes un pequeño resumen de las mejores practicas para que las tengas presentes:
- Indente su código,
- Añada espacios de separación entre secciones de código,
- Comente lo más que pueda el código,
- Crear variables con nombres descriptivos de sus funciones,
- Utilice la sintaxis VARIABLE=$(comando) para la sustitución de comandos
- Utilice módulos y / o variables de: Validación de Superusuario y Usuario Autorizado con o sin contraseñas establecidas.
- Utilice módulos y / o variables de: Validación del Sistema Operativo (Distro, Versión, Arquitectura, entre otros.),
- Utilice módulos (procedimientos / secciones) de confirmación de ejecución de acciones (actividades / funciones) criticas o por lotes,
- Provea Interfaces Amigables al usuario (Userfriendly): Por Terminal (con Menús y Colores usando Dialog) y / o Por Escritorio (con Ventanas usando Zenity y Gxmessage),
- Incluya módulos de (mensajes) de Bienvenida y Despedida al usuario, en caso de ser necesarios,
- Incluya un modulo de verificación de doble ejecución,
- Racionalice el tamaño del script con Funciones y / o Módulos externos,
- Invoque de forma clara y evidente los llamados a otros Interpretes,
- Aplique cualquier otra recomendación lógica y racional que considere necesaria.
A continuación un ejemplo de un Modulo de Variables de Entorno para un Script de Shell en Bash para Linux. Este debería ser el modulo (sección) que contenga todas aquellas seguras o probables variables que el Script de Shell necesita o necesitará para su ejecución. Yo personalmente agrego las siguientes:
###############################################################################
# INICIO DEL MODULO DE VARIABLES DE ENTORNO DEL SCRIPT
###############################################################################
NOM_SCRIPT=lpi_sb8_inicio_2016.sh
# echo $NOM_SCRIPT
# Almacenar como una variable predeterminada el Nombre real del Script
USR1_VALID=sysadmin
# echo $USR1_VALID
# Almacenar como una variable predeterminada el Nombre de Usuario valido que podrá ejecutar el Script.
# Haga una variable por cada Usuario Autorizado.
PASSWD_VALID=lpi*sb8
# echo $PASSWD_VALID
# Almacenar como una variable predeterminada el Nombre de la contraseña valida que permitirá ejecutar el Script.
# Haga una variable por cada contraseña de cada Usuario Autorizado.
S_O_VALID=kali
# echo $S_O_VALID
# Almacenar como una variable predeterminada el tipo de Sistema operativo valido para donde debe ser ejecutado el Script.
HOST_VALID=hostmovil-sysadmin
# echo $HOST_VALID
# Almacenar como una variable predeterminada el nombre del host valido donde debe ser ejecutado el Script.
IP_VALID=192.168.1.107
# echo $IP_VALID
# Almacenar como una variable predeterminada el nombre del host valido donde debe ser ejecutado el Script.
MAC_VALID=44:8a:5b:f0:3d:f3
# echo $MAC_VALID
# Almacenar como una variable predeterminada el nombre del host valido donde debe ser ejecutado el Script.
FILE_LOCK=lpi_sb_file_lock.txt
# echo $FILE_LOCK
# Almacenar el nombre de archivo predeterminada por el sistema para evitar doble ejecuciones ó detectar ejecuciones fallidas.
IDSUPERUSER=$(id -u | awk '{print $1}')
# IDSUPERUSER=$(echo $UID)
# IDSUPERUSER=$(getent passwd $USER | cut -d: -f3)
# echo $IDSUPERUSER
# Almacenar IUD del Superusuario root
USER_NAME_1=$(cat /etc/passwd | grep 1000 | cut -d: -f1 | awk '{print $1}')
HOME_USER_NAME_1=/home/$USER_NAME_1
# echo $USER_NAME_1 $HOME_USER_NAME_1
# Almacenar el nombre del usuario 1000 y su /home. Probable unico y primer Usuario del Sistema.
USER_NAME_2=$(cat /etc/passwd | grep 1001 | cut -d: -f1 | sed -n '2p' | awk '{print $1}')
HOME_USER_NAME_2=/home/$USER_NAME_2
# echo $USER_NAME_2 $HOME_USER_NAME_2
# Almacenar el nombre del usuario 1001 y su /home. Probable segundo Usuario del Sistema.
ID_USERNAME_SESSION=$(for i in $(who | sed 1q | cut -c 1-8); do grep $i /etc/passwd | awk '{print "\t" $1}' | tr -d '[A-Za-z]' | sed 's/::x*//' | cut -c 1-5 | awk '{print $1}' ; done | sed 1q)
# echo $ID_USERNAME_SESSION
# Almacenar el ID del Nombre del primer usuario (alfabeticamente) detectado conectado (con sesión abierta) en el sistema.
USERNAME_ID_SESSION=$(for i in $(who | sed 1q | cut -c 1-8); do grep $i /etc/passwd | awk '{print "\t" $1}' | tr -d '[A-Za-z]' | sed 's/::x*//' | cut -c 1-5 | awk '{print $2}' ; done ; echo $i)
# echo $USERNAME_ID_SESSION
# Almacenar el Nombre del primer usuario (alfabeticamente) detectado conectado (con sesión abierta) en el sistema.
# ID_FIRST_USERNAME=$(for i in 1000 1001 1002 1003 1004; do grep $i /etc/passwd | awk '{print "\t" $1}' | tr -d '[A-Za-z]' | sed 's/::x*//' | cut -c 1-5 | awk '{print $1}' ; done | sed -n '1p')
# echo $ID_FIRST_USERNAME
# Almacenar el ID del Nombre del primer usuario creado en el sistema entre los ID del 1000 al 1005.
# Nota: Solo funciona con la opción -o desactivada del MODO BASH ESTRICTO ó SEGURO (Bash Strict Mode / BSM)
# ID_FIRST_USERNAME=$(for i in $(seq 1000 1999); do grep $i /etc/passwd | awk '{print "\t" $1}' | tr -d '[A-Za-z]' | sed 's/::x*//' | cut -c 1-5 | awk '{print $1}' ; done | sed -n '1p')
# echo $ID_FIRST_USERNAME
# Almacenar el ID del Nombre del primer usuario creado en el sistema.
# Nota: Solo funciona con la opción -o desactivada del MODO BASH ESTRICTO ó SEGURO (Bash Strict Mode / BSM)
UBICACION=$(echo $PWD)
# UBICACION=$(pwd)
# echo $UBICACION
# Almacenar ruta de ejecución del Script LPI-SB
FECHA_SISTEMA_AN=$(date +"%d %b %y")
# echo $FECHA_SISTEMA_AN
# Almacenar la fecha Alfanumerica actual del Equipo
FECHA_SISTEMA_N=$(date +"%d %m %y")
# echo $FECHA_SISTEMA_N
# Almacenar la fecha Numerica actual del Equipo
DIA_ACTUAL=$(date +"%d")
# echo $DIA_ACTUAL
# Almacenar el día actual del Equipo
MES_ACTUAL_A=$(date +"%b")
# echo $MES_ACTUAL_A
# Almacenar el mes alfabetico actual del Equipo
MES_ACTUAL_N=$(date +"%m")
# echo $MES_ACTUAL_N
# Almacenarel mes numerico actual del Equipo
ANO_ACTUAL_2C=$(date +"%y")
# echo $ANO_ACTUAL_2C
# Almacenar el año (con 2 cifras) actual del Equipo
ANO_ACTUAL_4C=$(date +"%Y")
# echo $ANO_ACTUAL_4C
# Almacenar el año (con 4 cifras) actual del Equipo
HORA_SISTEMA=$(date +"%H:%M")
# echo $HORA_SISTEMA
# Almacenar la Hora actual del Equipo
HORA_ACTUAL=$(date +"%H")
# echo $HORA_ACTUAL
# Almacenar la Hora actual del Equipo
MINUTOS_ACTUAL=$(date +"%M")
# echo $MINUTOS_ACTUAL
# Almacenar la Hora actual del Equipo
TIPO_S_O_L=$(uname -o)
# echo $TIPO_S_O_L
# Almacena el nombre largo del tipo de Sistema Operativo encontrado.
TIPO_S_O_C=$(uname -s)
# echo $TIPO_S_O_C
# Almacena el nombre corto del tipo de Sistema Operativo encontrado.
NOM_DISTRO_L=$(cat /etc/os-release | grep NAME | grep -v "VERSION" | sed -n '2p' | cut -f2 -d\")
# NOM_DISTRO_L=$(lsb_release -d | sed 's/Description://')
# echo $NOM_DISTRO_L
# Almacena el nombre largo de la Distro detectada.
NOM_DISTRO_C=$(cat /etc/os-release | grep NAME | grep -v "VERSION" | sed -n '2p' | cut -f2 -d\" | awk '{print $1}')
# NOM_DISTRO_C=$(lsb_release -d | sed 's/Description://' | awk '{print $1}')
# echo $NOM_DISTRO_C
# Almacena el nombre corto de la Distro detectada.
ID_DISTRO=$(cat /etc/os-release | grep ID | grep -v "VERSION_ID" | grep -v "ID_LIKE" | sed 's/ID=//' | sed 's/"//g')
# ID_DISTRO=$(lsb_release -i | awk '{print $3}')
# echo $ID_DISTRO
# Almacena el ID de la Distro detectada.
VER_DISTRO=$(cat /etc/os-release | grep VERSION= | sed -n '1p' | sed 's/VERSION=//' | sed 's/"//g')
# VER_DISTRO=$(lsb_release -c | sed 's/Codename://')
# echo $VER_DISTRO
# Almacena el nombre de la versión de la Distro detectada.
ID_VER_DISTRO=$(cat /etc/os-release | grep VERSION_ID= | sed -n '1p' | sed 's/VERSION_ID=//' | sed 's/"//g')
# ID_VER_DISTRO=$(lsb_release -r | sed 's/Release://')
# echo $ID_VER_DISTRO
# Almacena el ID de la versión de la Distro detectada.
ARQ_DISTRO_COD=$(uname -m)
# echo $ARQ_DISTRO_COD
# Almacenar el Tipo de Arquitectura de la Distro detectada en forma codificada.
ARQ_DISTRO_COD=$(uname -m) ; if [[ "$ARQ_DISTRO_COD" = "x86" ]]; then ARQ_DISTRO_HUM=32; else ARQ_DISTRO_HUM=64; fi
# echo $ARQ_DISTRO_HUM
# Convertir el Tipo de Arquitectura de la Distro detectada en forma codificada a forma humana.
VER_KERNEL=$(uname -r)
# echo $VER_KERNEL
# Almacenar el Nombre del Arquitectura de la Distro detectada.
NOM_HOST=$(cat /etc/hostname)
# echo $NOM_HOST
# Almacenar el Nombre del Host donde se ejecuta el Script.
IP_ETH0=$(ifconfig eth0 | grep inet | grep -v inet6 | cut -d ":" -f 2 | cut -d " " -f 1)
MAC_ETH0=$(ifconfig eth0 | sed -n '1p' | awk '{print $5}')
# IP_INTERNA=$(hostname -I)
# echo $IP_ETH0 $MAC_ETH0
# Almacenar la IP / MAC del Host donde se ejecuta el Script.
echo "Variables de entorno cargadas sin errores, en 5 segundos la aplicación continuará ejecutandose"
sleep 5
###############################################################################
# FINAL DEL MODULO DE VARIABLES DE ENTORNO DEL SCRIPT
###############################################################################
===============
Nota: Dependiendo que sus requerimientos o implementaciones puede agregar la orden de comando export mi_variable debajo de cada una de las anteriores variables creadas ó crear y exportar sus propias variables creadas directamente con la orden de comando export mi_variable=mis_parámetros
Más adelante, en futuras entradas continuaremos viendo ejemplo de módulos (secciones) que realicen funciones tales como:
- MODULO DE DETECCIÓN DE DOBLE EJECUCIÓN ó EJECUCIONES FALLIDAS
- MODULO DE OPTIMIZACIÓN
- MODULO DE AUTORIZACIÓN DE USUARIO CON CONTRASEÑA
- MODULO DE DETECCIÓN DE ARQUITECTURA DEL SISTEMA OPERATIVO
- MODULO DE CONFIGURACIÓN DEL LENGUAJE DE CODIFICACIÓN
- MODULO DE CONFIGURACIÓN DE PROXY PARA EL AMBIENTE DE EJECUCIÓN
Entre muchos otros!
Pueden ir aprendiendo de forma autodidacta sobre los comandos: gksu, dialog, gxmessage, zenity, espeak, play, entre muchos otros más para crear interfaces gráficas por Terminal o para el Escritorio del Usuario, con alertas sonicas o multimedias, e ir adelantando conocimientos que usarán más adelante.
Recuerden que estas y cualquier otras recomendaciones sobre algún modulo, función, variable, comando u acción en general puede llevarse a cabo de muchas maneras, y lo aquí mostrado no es más que una sencilla manera, de las muchas maneras posibles y probables en la que dicha acción puede o podría ser llevada a cabo!
Solo para finalizar les dejo, un Screencast realizado por mí, para demostrarles de que serian capaces ustedes mismo, luego de finalizado este Curso online de Shell Scripting en DesdeLinux:
ScreenCast de Testeo del LPI-SB8
(LINUX POST INSTALL – SCRIPT BICENTENARIO 8.0.0) – Parte 2
Date for humans :
echo -e «\e[1;32mFecha:» $(date «+%d-%m-%Y») «\e[1;32m Hora:» $(date «+%T»)
True «uname -s» :
cat /proc/sys/kernel/ostype
Distro name :
cat /etc/*release | cut -f2 -d» | head -1
Hostname :
cat /proc/sys/kernel/hostname
OS Architecture :
[[ -x /sbin/init ]] && file /sbin/init | awk ‘{print $7}’ | tr -d ‘,’ || [[ -x /lib/systemd/systemd ]] && file /lib/systemd/systemd | awk ‘{print $7}’ | tr -d ‘,’ 2> /dev/null
Kernel Version :
cat /proc/sys/kernel/osrelease
Me gusto mucho tu primera contribución «date for humans» ya que la salida quedaría como ejemplo:
Fecha: 11-02-2016 Hora: 16:04:10
Lo cual efectivamente en una ventana de dialog, zenity o gxmessage es muy digerible visualmente!
Con tu segunda sugerencia me gustaría colocarla así:
if true «uname -s» && cat /proc/sys/kernel/ostype; then echo «Sistema Operativo validado» ; fi | sed 1d
Y en fin, muchas gracias por tus enriquecedores aportes como siempre!