¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Programación Bash
Un programa o script escrito en bash, tiene por convenio extensión .sh y consiste en un archivo de texto en el que se incluyen los comandos que serán ejecutados uno tras otro hasta llegar a término.
Ejecución de scripts
Un script puede ejecutarse de varias maneras:
- Lanzar un nuevo Bash con el script como argumento: Con la sintaxis bash [nombre de script].sh. Se abre un nuevo Bash en el que se ejecuta el script y se cierra al terminar. El proceso del Bash padre lleva como prefijo un guión -.
- Ejecutar el script desde línea de comandos: Con la sintaxis [nombre del script].sh. Si el usuario que ejecuta el script no utiliza el Bash como intérprete de comandos, pueden producirse errores. Para evitarlo, puede forzarse el shell con el que se ejecutarán los comandos indicándolo en un comentario “especial” del script, que debe especificarse en la primera línea: #![ruta absoluta hasta el shell, por ejemplo: /bin/bash].
- Con un punto .: Idéntico a usar el comando source. Indica al bash que interprete las órdenes del archivo pasado como argumento. Sintaxis: .[nombre del script].
- Con el comando exec: Ejecuta los comandos del archivo pasado como argumento. Sintaxis: exec [nombre del script].sh.
En todos los casos el usuario debe tener permisos de ejecución, y la ruta del archivo con el código debe estar en la variable de entorno $PATH (a no ser que se especifique en la misma línea de comandos).
Buenas prácticas
Algunos consejos a la hora de realizar scripts en Bash, pueden ser:
- No poner a los scripts nombres de comandos ya existentes, ya que puede dar lugar a problemas (por ejemplo, existe un comando script). También es recomendable ponerles la expensión .sh para distinguirlos rápidamente.
- Se recomienda también usar varios terminales para el proceso de depuración, y de esta manera no tener que estar cerrando el editor, probando el script, abriendo el editor, etc.
- Se deben usar comentarios, con el carácter #, para incluir descripciones de lo que se está haciendo, para mejorar la comprensión del script.
Códigos de retorno
Cuando un script finaliza sin mayor problema retorna 0. Si se ha producido un error o se ha dado algún tipo de situación especial, retorna un valor comprendido entre 1 y 255.
Para conocer el valor de retorno del último comando ejecutado, podemos leerlo en la variable especial $?. Es recomendable guardar su valor en una variable, si queremos usar este valor después.
Si deseamos que nuestro script retorne un valor diferente de 0 cuando finalice, lo especificamos con el comando exit [valor de retorno].
El comando exit fuerza la finalización del script.
Ejecución condicional
Se puede especificar diferentes comandos en la misma línea separándolos con ;. De esta manera se ejecutarán uno detrás de otro, sin que se tenga en cuenta sus valores de retorno.
Si se separa con &&, el siguiente comando se ejecutará sólo si el anterior ha devuelto 0 (ejecución correcta).
Si dos comandos se separan con ||, el segundo comando se ejecutará sólo si el anterior ha devuelto un valor diferente de 0 (ejecución no correcta).
Para depurar, pueden usarse los comandos true y false: true siempre devuelve 0, y false siempre devuelve 1.
Variables especiales
Variables definidas por el shell Bash:
- $$: contiene el PID del shell que está en ejecución.
- $PPID: contiene el PID del proceso padre del shell que está en ejecución.
- $0: contiene el nombre del script en ejecución.
- $1, $2, $3, …: Argumentos pasados al script por línea de comandos. Para referenciar los parámetros de orden superior a 9, hay que poner llaves (ejemplo_ ${12}) con el fin de evitar ambigüedades. Se puede usar el comando shift para desplazar los parámetros n posiciones.
- $#: Número de parámetros de entrada del script.
- $* y $@: Contiene los parámetros pasados por la línea de comandos.
- $LINENO: Contiene el número de línea del script, en la que aparece este comando. Útil para depurar.
Comando test
El comando test efectúa una serie de comparaciones entre archivos, cadenas de caracteres, valores aritméticos y entorno del usuario, devolviendo los valores 0, si la comparación es correcta (expresión verdadera) y 1 si no es así. Tiene dos posibles sintaxis: test [expresión] y [ expresión ] (los espacios entre los corchetes son obligatorios).
- Test de archivos:
- -f [archivo]: verdadero si el archivo es de tipo estándar (file).
- -d [archivo]: verdadero si el archivo es de tipo directorio (directory).
- -r [archivo]: verdadero si el usuario tiene permiso de lectura del archivo (read).
- -w [archivo]: verdadero si el usuario tiene permiso de escritura del archivo (write).
- -x [archivo]: verdadero si el usuario tiene permiso de ejecución del archivo (execute).
- -e [archivo]: verdadero si el archivo existe (exist).
- -s [archivo]: verdadero si el archivo no está vacío (size).
- [archivo1] -nt [archivo2]: verdadero si archivo1 es más reciente que archivo2 (newer than).
- [archivo1] -ot [archivo2]: verdadero si archivo1 es más antiguo que archivo2 (older than).
- [archivo1] -ef [archivo2]: verdadero si archivo1 es igual que archivo2 (equal file).
- Test de cadenas de caracteres:
- -n [cadena]: verdadero si la cadena no es nula.
- -z [cadena]: verdadero si la cadena es nula.
- [cadena1] = [cadena2]: Verdadero si las dos cadenas son iguales.
- [cadena1] != [cadena2]: Verdadero si las dos cadenas no son iguales.
- Test aritmético:
- [valor1] -eq [valor2]: verdadero si ambos valores aritméticos son iguales (equal).
- [valor1] -ne [valor2]: verdadero si ambos valores aritméticos son diferentes (not equal).
- [valor1] -lt [valor2]: verdadero si valor1 es inferior al valor2 (lower than).
- [valor1] -le [valor2]: verdadero si valor1 es inferior o igual al valor2 (lower or equal).
- [valor1] -gt [valor2]: verdadero si valor1 es superior al valor2 (greather than).
- [valor1] -ge [valor2]: verdadero si valor1 es superior o igual al valor2 (greather or equal).
- Test de entorno de usuario:
- -o [opción]: verdadero si la opción del shell está activa.
- Combinación de expresiones (todas ls anteriores combinadas):
- ! [expresión]: Verdadero si la expresión es falsa.
- [expresión1] -a [expresión2]: and lógico entre ambas expresiones.
- [expresión1] -o [expresión2]: or lógico entre ambas expresiones.
Operaciones aritméticas
Bash ofrece las herramientas necesarias para realizar operaciones aritméticas.
expr
El comando expr es un comando externo del bash.
Su sintaxis es expr [expresión].
Algunos de sus operadores llevan \ delante para no confundirlos con caracteres especiales del Bash.
Es necesario insertar un espacio entre elementos para que sean reconocidos correctamente.
| Operadores aritméticos | Nombre | Operadores lógicos | Nombre |
|---|---|---|---|
| + | Suma | \| | OR lógico |
| - | Resta | \& | AND lógico |
| \* | Multiplicación | \< | menor que |
| / | División entera | \⇐ | menor o igual que |
| % | Módulo | \> | mayor que |
| \( … \) | Paréntesis | \>= | mayor o igual que |
| = | igual | ||
| != | desigual |
let
Comando interno del Bash, por lo que es más eficiente, ya que no tienen que crear un subproceso para ejecutarse.
No es necesario separar los elementos por un espacio, es más fácil trabajar con variables, ya que se pueden definir en una expresión y no es necesario incluir el símbolo $.
Tiene más opreadores que expr, son más comunes y no requieren del símbolo \ delante.
Tiene dos posibles sintaxis: let [expresión] o (([expresión])).
| Operadores aritméticos | Nombre | Operadores lógicos | Nombre | Otros operadores | Nombre |
|---|---|---|---|---|---|
| + | Suma | || | OR lógico | ~ | Negación binaria |
| - | Resta | && | AND lógico | » | Desplazamiento binatio a la derecha |
| * | Multiplicación | ! | Negación lógica | « | Desplazamiento binario a la izquierda |
| / | División entera | < | menor que | & | AND binario |
| % | Módulo | <= | menor o igual que | | | OR binario |
| ** | Potencia | > | mayor | ^ | XOR binario |
| = | Asignación | >= | mayor o igual que | var++, ++var | Incremento |
| == | Igual que | var--, --var | Decremento | ||
| != | Desigual |
Entrada de datos: read
El comando read permite introducir datos, de forma que sea posible realizar programas interactivos.
Se pasan a continuación de read las variables a las que se les asignarán los datos (números o cadenas de caracteres).
Si hay más datos que variables, a la última variable asignada se le asigna una cadena con todos los datos restantes.
Si hay menos datos que variables, las variables sin datos se considerarán nulas.
Si se llama read sin argumentos, la entrada pasara completa como cadena a la variable de Bash $REPLY.
Es posible que la entrada se ponga en la misma linea que una frase, con la opción -p, ejemplo:
read -p "¿Edad del capitán?" edad ¿Edad del capitán? 12 echo $edad 12
Estructuras de control
Permiten ejecutar comandos en función del resultado de una expresión.
Para este cometido son muy usados los comandos test y let.
if
Ejecuta una serie de comandos si la condición evaluada es verdad.
Sintaxis:
if [condición] then >[comandos si la condición es verdadera] else >[comandos si la condición es falsa] fi
for
Ejecuta la misma serie de comandos tantas veces como valores haya en una lista dada.
En cada iteración una variable toma el valor de la lista considerado en esa iteración.
Sintaxis:
for [variable] in [lista de valores] do > [Serie de comandos a ejecutar] done
Es muy interesante el uso de caracteres genéricos en el uso de directorios y archivos, a la hora de definir una lista.
while
Se ejecutarán una serie de comandos mientras la condición sea válida.
Sintaxis:
while [condición] do [Serie de comandos a ejecutar] done
