Saltar a contenido

Shellscripting

El shell scripting es una técnica que permite crear scripts —archivos de texto con instrucciones— para automatizar tareas y procesos repetitivos mediante un intérprete de comandos, como Bash. Es especialmente útil en sistemas operativos basados en Unix y Linux, donde facilita la administración del sistema, la ejecución de rutinas y la integración de herramientas.

Estos scripts no se compilan, sino que se ejecutan línea por línea por el shell, permitiendo realizar desde la manipulación de archivos hasta la ejecución automática de programas complejos.

Propuesta didáctica

En esta unidad vamos a comenzar a trabajar el RA7 de ASO:

RA7. Utiliza lenguajes de guiones en sistemas operativos, describiendo su aplicación y administrando servicios del sistema operativo.

Criterios de evaluación (RA7)

A lo largo de la unidad se trabajarán y evidenciarán los siguientes criterios:

  • CE7a: Se han utilizado y combinado las estructuras del lenguaje para crear guiones.
  • CE7b: Se han utilizado herramientas para depurar errores sintácticos y de ejecución.
  • CE7c: Se han interpretado guiones de configuración del sistema operativo.
  • CE7d: Se han realizado cambios y adaptaciones de guiones del sistema.
  • CE7e: Se han creado y probado guiones de administración de servicios.
  • CE7f: Se han creado y probado guiones de automatización de tareas.
  • CE7g: Se han implantado guiones en sistemas libres.
  • CE7h: Se han consultado y utilizado librerías de funciones.
  • CE7i: Se han documentado los guiones creados.

Contenidos

Bloque 1 — Fundamentos del Shell (Sesión 1–2) - ¿Qué es un shell? CLI vs GUI.
- Formato general de órdenes en GNU/Linux.
- Comandos básicos de terminal.
- Creación y ejecución de scripts: permisos y $PATH.
- Comentarios y buenas prácticas.

Bloque 2 — Elementos del lenguaje (Sesión 2–3) - Variables y parámetros ($0, $1, $#, $*, $?).
- Entrada/salida con echo y read.
- Operadores: aritméticos, relacionales y lógicos.
- Cálculo con let y expansión aritmética $(( )).

Bloque 3 — Control de flujo (Sesión 3–4) - Estructuras condicionales: if, elif, else, case.
- Bucles: for, while, until.
- break, continue, exit.

Bloque 4 — Estructuras y modularización (Sesión 4–5) - Vectores (arrays) y recorrido.
- Funciones, parámetros y retorno.
- source y organización del código.

Actividades iniciales

  1. Introduce el comando para mostrar tu ubicación actual en el sistema.
  2. Introduce el comando para listar los archivos y directorios en tu ubicación actual.
  3. Introduce el comando para crear un archivo vacío llamado prueba.txt en tu ubicación actual.
  4. Introduce el comando para cambiar al directorio raíz del sistema.
  5. Introduce el comando para crear un directorio llamado nuevo_directorio en tu ubicación actual.
  6. Introduce el comando para eliminar el directorio nuevo_directorio que creaste anteriormente.
  7. Introduce el comando para mostrar el contenido del archivo /etc/passwd.
  8. Introduce el comando para contar las líneas de un archivo llamado prueba.txt.
  9. Introduce el comando para buscar la palabra "root" en el archivo /etc/passwd.

Programación de Aula (6h)

Esta unidad se imparte en la primera evaluación, con una duración estimada de 6 sesiones lectivas, durante la última quincena de septiembre:

Sesión Contenidos Actividades Criterios trabajados
1 Presentación de la UD y objetivos de sesión Cuestionario inicial, AC101-AC103 CE7a, CE7b, CE7g y CE7i
2 Variables, entrada/salida y operadores AC104, AC105, AC106 CE7a, CE7b, CE7f y CE7i

Introducción

Para administrar sistemas operativos es crucial manejar y dominar las interfaces (terminales) disponibles que nos permiten gestionarlos. Entre dichas interfaces destacan los siguientes tipos:

  • De líneas de texto (CLI, Command-Line Interface, interfaz de línea de comandos),
  • Gráficos/ventanas (GUI, Graphical User Interface, interfaz gráfica de usuario),
  • De lenguaje natural (NUI, Natural User Interface, interfaz natural de usuario, ejemplo SIRI en IOS).

Este tema se centra en Sistemas basados en código libre del tipo UNIX, debido a su amplio despliegue en empresas para implementar servicios, más en concreto de distribuciones Linux/GNU.

El CLI de las distribuciones de Linux/GNU es conocido como Shell o terminal, con esta interfaz es posible crear cualquier comando que el usuario necesite, incluso para las tareas más específicas, debido a estar directamente conectado al Kernel a diferencia de las aplicaciones como se puede observar en la siguiente figura.

Estructura de Linux

NOTA

  • Por lo tanto, es buena práctica que el administrador del sistemas tenga conocimientos en el manejo y gestión del terminal Shell, así como en la programación de scripts.

Shell

  • En informática, el shell o intérprete de comandos, es el programa informático que permite a los usuarios interactuar con el sistema, procesando las órdenes que se le indican; además provee una interfaz de usuario para acceder a los servicios del sistema operativo.
  • Los comandos ejecutables desde el shell pueden clasificarse en internos (corresponden en realidad a órdenes interpretadas por el propio shell) y externos (corresponden a ficheros ejecutables externos al shell, conocidos como guiones o scripts).

IMPORTANTE:

  • Linux dispone de varios Shell diferentes csh, bash, sh, ksh, zsh, etc... A destacar:
  • sh (Bourne Shell): este shell fue usado desde las primeras versiones de Unix (Unix Versión 7). Recibe ese nombre por su desarrollador, Stephen Bourne, de los Laboratorios Bell de AT&T.
  • bash: fue desarrollado para ser un superconjunto de la funcionalidad del Bourne Shell, siendo el intérprete de comandos asignado por defecto a los usuarios en las distribuciones de Linux, por lo que es el shell empleado en la mayoría de las consolas de comandos de Linux. Se caracteriza por una gran funcionalidad adicional a la del Bourne Shell.
  • Para intentar homogeneizar esta diversidad de shells, el IEEE definió un estándar de «intérprete de comandos» bajo la especificación POSIX 1003.2 (también recogida como ISO 9945.2). La creación de dicho estándar se basó en la sintaxis que presentaban múltiples shells de la familia Bourne shell.
  • bash respeta completamente el estándar POSIX, sobre el que añade un número considerable de extensiones (estructura select, arrays, mayor número de operadores,…). En este tema utilizaremos el Shell de bash.

Formato comandos

En general, el formato de las órdenes de GNU/Linux es el siguiente:

  • Comando, que indica la acción que se va a ejecutar.
  • Modificadores, que cambian el comportamiento estándar del comando para adaptarlo a las necesidades.
  • Argumentos, elementos necesarios para realizar la acción del comando.

Warning

  • Un dato a tener en cuenta cuando se trabaja con un terminal, es que GNU/Linux distingue entre mayúsculas y minúsculas, es decir, la ejecución de comandos en el CLI de Linux es CASE SENSITIVE.

Principales comandos

Comando Acción Comando Acción
ls muestra el contenido de una carpeta uname muestra información del sistema
df muestra estado del disco cd cambiar de directorio
fsck comprueba integridad de discos mkdir crear directorios
mount monta particiones y volúmenes shutdown apaga el equipo (restart o reboot)
unmount desmonta particiones y volúmenes clear limpia la pantalla
fdisk administra particiones date/cal muestra hora/calendario del sistema
echo imprime por pantalla who muestra quien está conectado

Shell Script en GNU/Linux

  • Un Shell script (guion) es un archivo de texto que contiene una serie de comandos que, ordenados de forma específica, realizan la tarea para la que fueron diseñados, es decir, es un programa escrito de comandos Shell para ser ejecutados de forma secuencial.
  • De esta forma se pueden automatizar tareas repetitivas ahorrando tiempo al administrador.
  • Un programa escrito en shell se denomina shellscript, programa shell o simplemente un shell.

Estructura general

  • En su forma más básica, un shell-script puede ser un simple fichero de texto que contenga uno o varios comandos.
  • Para ayudar a la identificación del contenido a partir del nombre del archivo, es habitual que los shell scripts tengan la extensión «.sh»,
  • Se seguirá este criterio pero hay que tener en cuenta que es informativo y opcional.
#!/bin/bash
#*********************************
#Este es mi primer script
#*********************************
echo Hola Mundo
#Esto es un comentario, soy muy útil.

Creación Shell scripts

  • Para crear un script utilizaremos cualquiera de los editores de texto plano como vi, vim , nano.
  • Después de crear el archivo hay que dotarlo de permisos de lectura y ejecución.
chmod ugo=rx script.sh
  • Para ejecutar el archivo: (ubicados en la carpeta que contiene el archivo), se pueden utilizar el siguiente archivo:

    ./script.sh
    
  • Además se puede utilizar otro método que consiste en definir la carpeta dentro de la variable de entorno PATH (editando el fichero .bashrc.) Una vez realizado ya se podría ejecutar directamente el fichero con el nombre del script.

    mkdir /home/administrador/scripts
    PATH=$PATH:/home/administrador/scripts
    export PATH
    

NOTA

  • La primera forma ejecutará el contenido del shell script en un subshell o hilo del terminal original. El programa se ejecuta hasta que se terminan las órdenes del archivo, se recibe una señal de finalización, se encuentra un error sintáctico o se llega a una orden exit. Cuando el programa termina, el subshell muere y el terminal original toma el control del sistema.
  • Esto no ocurre si se usa la opción de PATH, la cual ejecuta el contenido del shell script en el mismo terminal donde fue invocado.

El primer Shellscript

  • Crea un ejemplo llamado listar.sh, se aconseja ejecutar los siguientes comandos de forma secuencial.
cd ~
mkdir scripts
cd scripts
touch listar.sh
nano listar.sh
  • Genera, guarda y prueba el siguiente código.
#! /bin/bash
clear
ls -la
echo “Listado realizado el $(date)

Comentarios

  • Para realizar un comentario se usa el carácter #
  • Cuando el terminal encuentra una línea que comienza con este carácter, ignora todo lo que existe desde él hasta el final de línea.
  • A esta regla existe una excepción:
    #!/bin/bash

Info

  • Es el "Shebang" Indica el terminal que será utilizado por el shell script, no un comentario.
  • Esta línea debe ser la primera del fichero que, aún siendo opcional, indica el tipo de lenguaje en el que ha sido escrito el programa.
  • Si la versión de GNU/Linux dispone de el terminal especificado en esta línea, ejecutará el código con él, si no es así, utilizará el que por defecto tenga asignado el usuario que lo ejecuta.

Depuración

Esta tarea no es sencilla en ShellScripting, aun así se recomienda los siguientes métodos de depuración, apoyados en los siguientes argumentos a la hora de ejecutar el script:

  • -x → Expande cada orden simple, e imprime por pantalla la orden con sus argumentos, y a continuación su salida.
  • -v → Imprime en pantalla cada elemento completo del script (estructura de control, …) y a continuación su salida.

Además en el propio Script se pueden utilizar los siguientes comandos:

Comando Acción
set -x set –xv Activa las trazas/verbose. Se debe ubicar justo antes del trozo del script que se desea depurar.
set +x set +xv Desactiva las trazas/verbose. Ubicarlo justo después del trozo del script que se desea depurar.

Sintaxis

Argumentos o Parámetros

  • Son especificaciones que se le hacen al programa al momento de llamarlo.
  • Introducen un valor, cadena o variable dentro del script.
  • Utilización de parámetros:
Símbolo Función
$1 representa el 1º parámetro pasado al script
$2 representa el 2º parámetro
$3 representa el 3º parámetro (podemos usar hasta $9)
$* representa todos los parámetros separados por espacio
$# representa el número de parámetros que se han pasado
$0 representa el parámetro 0, es decir, el nombre del script o el nombre de la función
  • Ejemplo:
#!/bin/bash
echo ‘El primer parámetro que se ha pasado es  $1
echo ‘El tercer parámetro que se ha pasado es  $3
echo ‘El conjunto de todos los parámetros :  $*
echo ‘Me has pasado un total de  $#  parámetros’”
echo ‘El parámetro 0 es :  $0
#Fin del script
  • Si por ejemplo se enviasen los siguientes parámetros:
./script.sh  Caballo  Perro  675 Nueva
  • Se obtendría la siguiente salida:
El primer parámetro que se ha pasado es Caballo
El tercer parámetro que se ha pasado es 675
El conjunto de todos los parámetros : Caballo Perro 675 Nueva
Me has pasado un total de 4 parámetros
El parámetro 0 es : ./script.sh

Info

  • Argumento especial $?
  • Contiene el valor que devuelve la ejecución de un comando.
  • Puede tener dos valores: cero si se ha ejecutado bien y se interpreta como verdadero, o distinto de cero si se ha ejecutado mal y se interpreta como falso.
    • 0 -> Si el último comando se ejecutó con éxito
    • !0 -> Si el último comando no de ejecutó con éxito

Variables

  • Es un parámetro que cambia su valor durante la ejecución del programa.
  • Se da un nombre para identificarla y recuperarla, antecedido por el carácter $.

Info

  • En shellscript no se declaran y no importa el tipo.
  • El nombre de la variable puede estar compuesto por letras y números y por el carácter subrayado “_”.
  • Ejemplo:
#! /bin/bash
#*********************************
#Este es mi segundo script
#*********************************
MIVARIABLE=‘Administración de Sistemas Operativos ASO’
echo $MIVARIABLE

Warning

  • Deben empezar por letra o “_
  • En ningún caso pueden empezar por un número, ya que esa nomenclatura está reservada a los parámetros.
  • El contenido de estas variables será siempre tomado como si fuesen cadenas alfanuméricas, es decir, serán tratadas como cadenas de texto. Por lo tanto se necesitan operandos o comandos específicos para realizar operaciones con valores numéricos de las variables. Explicado en el apartado de Operadores Aritméticos.

Variables de entorno

  • Cada terminal durante su ejecución tiene acceso a dos ámbitos de memoria:
    1. Datos Locales Una variable declarada en un terminal solo será accesible desde el terminal en el que declara.
    2. Datos Global Engloban a todos los terminales que se estén ejecutando. Son las denominadas Variables de Entorno.

Ejemplo de principales variables de entorno:

Variable Función
$BASH Ruta del programa Bash
$HOME Ruta completa del home del usuario
$PATH Lista los directorios de donde se buscan los programas
$RANDOM Devuelve un valor numérico aleatorio

Entrada y salida del Shell Script

  • Para poder interactuar con un programa de terminal es necesario disponer de un mecanismo de entrada de datos.
  • Para dinamizar el resultado de los shell scripts y un dispositivo de salida que mantenga informado al usuario en todo momento de los que está ocurriendo.
  • Para la entrada de datos se utiliza el comando read y para la salida el comando echo.

echo

  • Su tarea es la de mostrar información con mensajes de texto lanzados por pantalla
Modificador Función
-e para usar las opciones hay que utilizar este modificador
\c Sirve para eliminar el salto de línea natural del comando echo.
\n nueva línea.
\t tabulador horizontal.
\v tabulador vertical.

Info

  • Si se antepone el símbolo del dólar delante de una variable, mostrará su contenido.
  • Si es necesario mostrar frases con espacios, debe situarse entre comillas.

Warning

  • La orden echo permite expandir variables siempre que se usen las comillas dobles.
  • Ejemplo:
    #!/bin/bash
    NOMBRE=Javi
    echo “hola $NOMBRE
  • El texto mostrado por pantalla será: hola javi

read

  • Esta herramienta asigna el texto que el usuario ha escrito en el terminal a una o más variables.
  • Lo que hace read es detener la ejecución del shell script y pasa el testigo al usuario.
  • Hasta que éste no introduzca los datos, la ejecución del programa no avanzará.

  • Ejemplo:

    #!/bin/bash
    echo “Introduce tu nombre: read NOMBRE
    echo “Hola $NOMBRE

Info

Cuando se utiliza read con varios nombres de variables, el primer campo tecleado por el usuario se asigna a la primera variable, el segundo campo a la segunda y así sucesivamente

  • Ejemplo:
    #!/bin/bash
    read -p “Introduce tres números (separados por un espacio):  num1 num2 num3
    echo “Los número introducidos son $num1, $num2 y $num3

Info

En este ejemplo se ha usado el modificador -p el cual permite imprimir un mensaje antes de la recogida de los datos, prescindiendo de primer comando echo del ejemplo anterior.

Operadores en shell script

  • Todas las variables creadas en un terminal se tratan como cadenas de texto, incluso si su contenido es solo numérico.
  • Este es el motivo por el cual si lanzamos el siguiente código, no se obtendrá el resultado esperado:
#!/bin/bash
var1=15
var2=5
echo $var1+$var2

Warning

  • La salida de este programa no será un número 20, sino la cadena de caracteres 15+5.
  • Esto es así porque la suma de cadenas de texto, son esas cadenas de texto unidas de forma consecutiva.
  • Existen tres tipos de operadores según el trabajo que realicen: aritméticos, relacionales y lógicos

Aritméticos

  • Los operadores aritméticos realizan operaciones matemáticas, como sumas o restas con operandos.
  • "Manipulan" datos numéricos, tanto enteros como reales.
Símbolo Función
+ suma
- resta
* multiplicación
/ división
% modulo (resto)
= asignación
  • Ejemplo:
#!/bin/bash
#*********************************
#Esto es mi tercer script
#*********************************

NUMERO=4
let SUMA=NUMERO+3
echo $SUMA
NUMERO=5
let SUMA=NUMERO+5
echo $SUMA
NUMERO=10
let SUMA=NUMERO-10

Relacionales

  • Este tipo de operadores tan sólo devuelven dos posibles valores; verdadero o falso.
  • Existen subtipos según se comparen cadenas o números.

    1. Operadores relacionales para números

    Operador Acción
    -eq Comprueba si dos números son iguales.
    -ne Detecta si dos números son diferentes.
    -gt Revisa si la izquierda es mayor que derecha.
    -lt Verifica si la izquierda es menor que derecha.
    -ge Coteja si la izquierda es mayor o igual que derecha.
    -le Constata si la izquierda es menor o igual que derecha.

    2. Operadores relacionales para cadenas de texto o de cuerda

    Operador Acción
    -z Comprueba si la longitud de la cadena es cero.
    -n Evalúa si la longitud de la cadena no es cero.
    = Verifica si las cadenas son iguales.
    != Coteja si las cadenas son diferentes.
    cadena Revisa si la cadena es nula.

    3. Operadores relacionales para archivos y directorios

    Operador Acción
    -a Comprueba si existe el archivo.
    -r Evalúa si el archivo esta vacío.
    -w Confirma si existe el archivo y tiene permisos de escritura.
    -x Constata si existe el archivo y tiene permisos de ejecución.
    -f Escruta si existe y es un archivo de tipo regular.
    -d Escruta si existe y es un archivo de tipo directorio.
    -h Coteja si existe y es un enlace.
    -s Revisa si existe el archivo y su tamaño es mayor a cero.

Lógicos

  • Se utilizan para evaluar condiciones, no elementos.
  • Comprueba el resultado de dos operandos y devuelve verdadero o falso en función del valor que arrojen los operandos.
  • Los tipos son:
Operador Acción
&& AND, devuelve verdadero si todas condiciones que evalúa son verdaderas. Se puede representar: -a o &&.
|| OR, da como resultado verdadero si alguna de las condiciones que evalúa es verdadera. Se representar: -o o ||.
! negación, invierte el significado del operando. de verdadero a falso, y viceversa. Con ! o not.

Info

Para realizar cálculos aritméticos es necesario utilizar expresiones como expr, let o los expansores.

expr

  • Este comando toma los argumentos dados como expresiones numéricas, los evalúa e imprime el resultado.
  • Cada término de la expresión debe ir separado por espacios en blanco.
  • Soporta diferentes operaciones: sumar, restar, multiplicar y dividir enteros utilizando los operadores aritméticos para el cálculo del módulo.

Tip

  • MEJOR NO UTILIZAR
  • Desafortunadamente, expr es difícil de utilizar debido a las colisiones entre su sintaxis y la propia terminal.
  • Puesto que * es el símbolo comodín, deberá ir precedido por una barra invertida para que el terminal lo interprete literalmente como un asterisco.
  • Además, es muy incómodo de trabajar ya que los espacios entre los elementos de una expresión son críticos.
  • Ejemplo:
    #!/bin/bash
    var=5
    resultado=`expr $1 + $var + 1
    echo $resultado`
    

let

  • Facilita la sintaxis de estas operaciones aritméticas reduciéndolas a la mínima expresión.
  • No es necesario incluir el símbolo del dólar que precede a las variables.
  • Se configura como un comando más cómodo de ejecutar.

  • Ejemplo:

    #!/bin/bash
    var=5
    let resultado=$1+var+1
    echo $resultado
    

expansores

  • Para las operaciones aritméticas se utilizan los dobles paréntesis.
  • Realizan la operación contenida dentro de ellos lanzando la ejecución fuera de ellos una vez resuelta.

  • Ejemplo:

    #!/bin/bash
    var=5
    echo $(($1+$var+1))
    echo $(($1 + $var + 1))
    

Tip

Consejo de uso, ya que es mucho más intuitivo que las anteriores expresiones.

Redirecciones

  • Una redirección consiste en trasladar la información de un fichero de dispositivo a otro.
  • Para ello se utilizan los siguientes símbolos:

    Símbolo Acción
    < redirecciona la entrada desde el fichero stdin (entrada estándar)
    > envía la salida de stdout (salida estándar) a un fichero especificado
    >> añade la salida de stdout (salida estándar) a un fichero especificado
    2> envía la salida de stderr (error estándar) a un fichero especificado
    * Ejemplo:
sh script.sh 2>/dev/null

Info

El objetivo de la expresión anterior puede ser utilizada en la administración de sistemas para descartar el error estándar de un proceso, de esta forma no aparecerán los mensajes de error por el terminal; es muy utilizado.

Tuberías

  • Forma práctica de redireccionar la salida estándar de un programa hacia la entrada estándar de otro.
  • Esto se logra usando el símbolo | (pipeline). Ejemplo:
$ cat archivo.txt | wc

Info

El comando anterior utiliza tuberías para redireccionar la salida estándar del comando cat y pasarla como entrada estándar del comando wc para contar las líneas y palabras de un archivo.

alias

  • Alias es un comando que se ejecuta desde un terminal que permite configurar vínculos entre varios comandos.
  • Cada usuario puede asignar una palabra fácil de recordar a uno o más comandos que, por lo general, pueden ser más complicados de recordar.
  • Ejemplo:
alias listado=’ls -lia>’

Actividades

Formato de entrega

Escribe el código de los scripts en ShellScript que se detallan en cada ejercicio. Deberás crear un fichero de texto para cada ejercicio con el siguiente nombre: ejXXX.sh, donde las X representan el número de ejercicio. Una vez terminada la práctica, comprime todos estos ficheros en uno y súbelos al Moodle

```

  • AC101. (RA.7 // CE7a, CE7b, CE7g y CE7i // 1-3p) Crea un shell script que muestre por pantalla el mensaje “¡Hola Mundo!”.

  • AC102. (RA.7 // CE7a, CE7b, CE7g y CE7i // 1-3p) Realiza un script que guarde en un fichero el listado de archivos y directorios de la carpeta etc, a posteriori que imprima por pantalla dicho listado.

  • AC103. (RA.7 // CE7a, CE7b, CE7g y CE7i // 1-3p) Modifica el script anterior para que además muestre por pantalla el número de líneas del archivo y el número de palabras.

  • AC104. Crea un shell script que muestre por pantalla el resultado de de las siguientes operaciones. Debes tener en cuenta que a, b y c son variables enteras que son preguntadas al usuario al iniciar el script.
    • a%b
    • a/c
    • 2 * b + 3 * (a-c)
    • a * (b/c)
    • (a*c)%b

  • AC105. Realiza un script que muestre por pantalla los parámetros introducidos separados por espacio, el número de parámetros que se han pasado, y el nombre del script.

  • AC106. Diseña un script en Shell que pida al usuario dos números, los guarde en dos variables y los muestre por pantalla.

  • AC107. Genera un script que muestre los usuarios conectados en el sistema operativo, comprobando que son usuarios dados de alta en el mismo.