Shell Scripting
Shell Scripting
Bash (Bourne-Again Shell) es un intérprete de comandos de Unix. Este lee los comandos
del shell e interactúa con el sistema operativo para ejecutarlos.
Para entender completamente el scripting shell bash, necesitas conocer dos conceptos:
shell y scripting.
Cuando escribes bash en un editor de texto, estás compilando comandos bash o funciones
bash, los cuales son un conjunto de comandos que pueden ser llamados numerosas veces tan solo
usando el nombre de la función. El texto se guarda entonces como un archivo de script bash
ejecutable con la extensión .sh. (B., 2023)
¿Qué puedo hacer con BASH?
Los scripts Bash pueden ayudarte con tu flujo de trabajo, ya que compilan muchos
comandos largos en un único archivo de script ejecutable.
Por ejemplo, si tienes múltiples comandos que tienes que ejecutar en un intervalo de
tiempo específico, puedes compilar un script bash, en lugar de escribir y ejecutar los comandos
manualmente uno por uno. Sólo tendrás que ejecutar el archivo de script cuando sea necesario.
(B., 2023)
Comandos bien estructurados. Estructura los comandos en una secuencia para que
cada vez que ejecutes el script, se ejecute en el orden correcto.
Automatización de tareas. Automatiza la ejecución de secuencias de comandos en
cualquier momento definido mediante el programador cron basado en el tiempo.
Transparencia. La gente puede comprobar el contenido de un script ya que está en
un archivo de texto legible. Sin embargo, si ejecutas los comandos utilizando otro
programa escrito en un lenguaje de programación diferente, como C++, tendrás
que acceder al código fuente.
Transferible. Si transfieres un script a otras distribuciones de Linux, seguirá
funcionando, siempre que los comandos del shell estén disponibles en ese sistema
operativo específico.
Historia y versiones
Bash es un programa shell escrito por Brian Fox como una versión mejorada del
programa ‘sh’ de Bourne Shell. Es un proyecto GNU de código abierto. Fue lanzado en 1989
como una de las distribuciones shell más populares de los sistemas operativos GNU/Linux.
Proporciona mejoras funcionales sobre Bourne Shell tanto para programación como para usos
interactivos. Incluye edición de línea de comandos, combinación de teclas, historial de comandos
con tamaño ilimitado, etc. (Velazquez, 2023)
Brian Fox fué quien programó las primeras versiones de Bash y continuó actualizándolo
hasta 1993. A principios de 1989, Chet Ramey empezó a ayudar a Brian y fué el responsable de
muchos arreglos en el código y nuevas características.
Chet Ramey es ahora el mantenedor oficial del shell bash sindo la última versión la 2.x.
Si bien bash y zsh son shells poderosos y comparten muchas características destacadas,
también poseen distinciones por las cuales los usuarios pueden tener diferentes preferencias.
Concepto de Scripting.
Según (Gonzàlez, 2011) un script es un conjunto de órdenes y llamadas a programas que,
junto a una serie de estructuras de control básicas, se utiliza para automatizar tareas en un
sistema operativo, podríamos definirlo también de la siguiente manera un script hace referencia a
una secuencia de comandos o “guion” que indica al ordenador las instrucciones que debe
realizar.
Todos los lenguajes de scripting son, por lo tanto, lenguajes de programación, mientras
que lo contrario no es cierto.
La diferencia entre lo que es un lenguaje de programación y un lenguaje de scripting
radica principalmente en cómo se utilizan. Los primeros son útiles para crear nuevos programas,
mientras que los segundos permiten proporcionar instrucciones a los programas existentes.
Variables en BASH.
Las variables de entorno se utilizan para almacenar algunos valores que pueden ser
utilizados por los scripts desde el shell. No estás limitado a las variables de entorno del shell,
puedes crear las tuyas propias.
Variables globales
Variables locales
La variable local es visible solo en el shell donde definió, mientras que la variable global
es visible para cualquier proceso en ejecución o que se ejecute desde el shell.
Variables globales
El sistema Linux establece algunas variables de entorno globales cuando inicias sesión en
tu sistema y siempre son en LETRAS MAYÚSCULAS para diferenciarlas de las variables de
entorno definidas por el usuario.
Si queremos ver las variables de entorno que estamos usando y que estan cargadas en
nuestra sesión, escribe el comando printenv o env:
~$ printenv
...
USER=JECD
CONDA_EXE=/anaconda2/bin/conda
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.JeacBiHuQB/
Listeners
_CE_CONDA= LSCOLORS=ExFxBxDxCxegedabagacad
PATH=/Users/JECD/edirect:/anaconda2/bin:/anaconda2/
condabin:/Users/JECD/.rbenv/shims:/usr/local/kSNP3:/Users/JECD/
Documents/SPAdes-3.13.0
Darwin/bin:/Applications/sratoolkit.2.9.2/bin:/Users/JECD/mview-
1.64/bin:/Users/JECD/Documents/bioinformaticsbinaries:/Users/
JECD/Documents/HTSeq-0.8.0/scripts:/Library/Python/2.7/site-
packages/ete3/tools:/Users/JECD/anaconda_ete/bin:/usr/local/
bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/git/
bin:/Users/JECD/Documents/ncbi-blast-2.6.0+/bin
CONDA_PREFIX=/anaconda2
PWD=/Users/JECD/Dropbox/informatica/BASH_scripting/if_loops
XPC_FLAGS=0x0
PS1=(base) \[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h:\[\
033[33;1m\]\w\[\033[m\]$
RBENV_SHELL=bash
...
Hay muchas variables de entorno globales, para imprimir solo una de ellas, escribe el
comando echo seguido de $NombreDeVariable. Ej: para imprimir la variable HOME escribe
echo $HOME
~$ echo $HOME
/Users/JECD
Variables locales
Para ver las variables globales y locales del shell que está ejecutando y las que están
disponible para ese shell, escribe el comando set.
Para declarar una variable en Shell escribe el nombreDeLaVariable que desees, seguido
de un signo igual y el valor SIN espacios:
~$ myName='Jesus'
~$ echo $myName
~$ Jesus
Una vez que hayas establecido tu variable local, será visible en el alcance del shell
actualmente en ejecución, esto significa que, si inicias otra ventana del shell, la variable no estará
disponible en esa nueva ventana.
Para declarar una variable de entorno global, debes declarar una variable de entorno local
y luego utilizar el comando export de la siguiente manera directamente en la shell:
~$ echo $myvar
~$ export myvar
Ahora, mientras tengamos abierta la terminal donde se exportó la variable myvar,
cualquier nueva ventana de terminal que abra tendrá acceso a dicha variable global.
~$ echo $myvar
Si queremos eliminar una variable global solo tendremos que utilizar el comando unset:
~$ unset myvar
~$ echo $myvar
echémosle un vistazo:
$ echo $PATH
/Users/JECD/edirect:/anaconda2/bin:/anaconda2/condabin:/
Users/JECD/.rbenv/shims:/usr/local/kSNP3:/Users/JECD/Documents/
SPAdes-3.13.0-Darwin/bin:/Applications/sratoolkit.2.9.2/bin:/
Users/JECD/mview
1.64/bin:/Users/JECD/Documents/bioinformaticsbinaries:/Users/JEC
D/Documents/HTSeq-0.8.0/scripts:/Library/Python/2.7/site
packages/ete3/tools:/Users/JECD/anaconda_ete/bin:/usr/local/bin:
/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/git/bin:/
Users/JECD/Documents/ncbi-blast-2.6.0+/bin
Asi es un poco engorroso, que tal si aplicamos lo aprendido en los bucles For
:/Users/JECD/edirect
:/anaconda2/bin
:/anaconda2/condabin
:/Users/JECD/.rbenv/shim
:/usr/local/kSNP3
:/Users/JECD/mview-1.64/bin
:/Users/JECD/Documents/bioinformaticsbinaries
:/Users/JECD/Documents/HTSeq-0.8.0/scripts
:/Library/Python/2.7/site-packages/ete3/tools
:/Users/JECD/anaconda_ete/bin
:/usr/local/bin
:/usr/bin
:/bin
:/usr/sbin
:/sbin
:/opt/X11/bin
:/usr/local/git/bin
:/Users/JECD/Documents/ncbi-blast-2.6.0+/bin
Como podeis observar hay un total de 8 entradas con los path de programas que puedo
ejecutar directamente en la shell, como blast, kSNP3 o HTSeq.
Si agregas una ruta de carpeta a la variable PATH, el shell buscará en esa carpeta
cualquier ejecutable que se ejecute cuando escribas cualquier comando.
Simplemente agrega la variable de ruta seguida de dos puntos y el nuevo directorio como
se muestra a continuación:
PATH=$PATH:/path/to/directory
aqui un ejemplo
~$ PATH=$PATH:/Users
:/Users
:/Users/JECD/edirect
:/anaconda2/bin
:/anaconda2/condabin
:/Users/JECD/.rbenv/shim
:/usr/local/kSNP3
:/Users/JECD/mview-1.64/bin
:/Users/JECD/Documents/bioinformaticsbinaries
:/Users/JECD/Documents/HTSeq-0.8.0/scripts
:/Library/Python/2.7/site-packages/ete3/tools
...
si queremos que la variable sea persistente tenemos que editar el archivo .bashrc
o .bash_profile en mac y añadirlo de la siguiente manera:
export PATH=$PATH:/path/to/directory
~$ mycurrentdir=$(pwd)
~$ echo $mycurrentdir
/Users/JECD
~$ mycurrentdir=`pwd`
~$ echo $mycurrentdir
/Users/JECD
Depuración.
Depurar en Bash
Para utilizar estas opciones que te ofrece Bash para depurar tus scripts, es necesario
que modifiques la primera línea de tu script, incluyendo una o mas de las opciones que Bash te
ofrece.
La opción de depuración -x
La primera de las opciones que te ofrece Bash para depurar tus scripts es -x. Esta opción
la puedes incluir en la cabecera de tu script de la siguiente forma,
!#/bin/bash -x
bash -x tu_script.sh
Pero ¿que hace la opción -x ? La opción -x lo que hace, básicamente, es imprimir cada
una de las instrucciones que se ejecutan en el script. De esta manera, puedes seguir de forma
sencilla la ejecución de tu script.
Podemos apreciarlo en un ejemplo, que siempre es mucho mas sencillo de entender. A
este ejemplo le llamaremos ejemplo.sh , y le daremos permisos de ejecución, chmod +x
ejemplo.sh .
#!/bin/bash -x
Si apreciamos mejor, antes de ejecutarse la primera línea del script este la imprime. De
esta manera podemos saber exactamente lo que estamos ejecutado. Para distinguirlo incluye
un + al comienzo de la línea.
Hemos modificado ligeramente el ejemplo anterior para que podamos ver el uso de set
-x y set +x . Fíjate,
#!/bin/bash
set -x
operacion=$((2+2))
set +x
+ operacion=4
+ set +x
¿Te has dado cuenta? Desde el momento que has establecido set -x se imprimen todas
las instrucciones hasta set +x inclusive.
La siguiente de las opciones que tenemos para depurar en Bash es -e . Esta opción lo que
hace es que cuando en nuestro script alguna instrucción de como resultado un valor distinto de
cero detendrá el script, es decir, directamente se saldrá del script sin continuar.
Se trata de una forma bastante sencilla de localizar donde se puede encontrar el error en
el script. Nuevamente mostramos un ejemplo para que podamos ver su utilidad. Primero, lo
haremos sin la opción -e .
#!/bin/bash -x
file=/no/existe
ls $file
echo $file
+ file=/no/existe
+ ls /no/existe
+ echo /no/existe
/no/existe
Sin embargo, si ejecutamos el script con bash -xe otro_ejemplo.sh el resultado es
significativamente distinto,
+ file=/no/existe
+ ls /no/existe
Como podemos apreciar al ejecutar ls $file y no existir el archivo por el que preguntas,
directamente termina la ejecución del script. Ya hemos localizado el error.
Indicarte que puedes utilizar bash -x -e o bash -xe o bash -ex es completamente
indistinto y el funcionamiento resultará ser exactamente igual.
Así como la opción para depurar en Bash -x expande los valores, la opción de
depuración -v imprime cada línea conforme la lee en el script, sin expandirla. Así, si ejecutas el
último de los ejemplos que has visto bash -xv otro_ejemplo.sh, el resultado será el siguiente,
#!/bin/bash -x
file=/no/existe
+ file=/no/existe
ls $file
+ ls /no/existe
echo $file
+ echo /no/existe
/no/existe
De esta forma podemos ver como escribimos cada una de las líneas del script y
exactamente como es interpretada.
Generando un número aleatorio y enviándolo a una variable.
Puedes generar un número aleatorio en Bash utilizando el comando `shuf` o `od`
combinado con `/dev/urandom`. Aquí tienes un ejemplo de cómo hacerlo y almacenarlo en una
variable:
```bash
# Generar un número aleatorio entre 1 y 100
numero=$(( (RANDOM % 100) + 1 ))
# Imprimir el número aleatorio
echo "Número aleatorio: $numero"
```
En este ejemplo, `(RANDOM % 100) + 1` genera un número aleatorio entre 1 y 100.
Luego, este número se asigna a la variable `numero`. Puedes ajustar el rango según tus
necesidades.
Si prefieres usar `shuf` o `od` para generar números aleatorios, aquí tienes otro ejemplo:
```bash
# Generar un número aleatorio entre 1 y 100
numero=$(shuf -i 1-100 -n 1)
# Imprimir el número aleatorio
echo "Número aleatorio: $numero"
```
O usando `od`:
```bash
# Generar un número aleatorio entre 1 y 100
numero=$(od -A n -N 2 -t d -An /dev/urandom | tr -d ' ')
# Asegurarse de que el número está dentro del rango deseado
numero=$(( numero % 100 + 1 ))
# Imprimir el número aleatorio
echo "Número aleatorio: $numero"
```
Cualquiera de estos métodos generará un número aleatorio y lo almacenará en la variable
`numero`.
Los comandos básicos de una shell varían según el sistema operativo y la shell específica
que estés utilizando. Sin embargo, aquí hay una lista de algunos comandos básicos que son
comunes en la mayoría de las shells tipo Unix/Linux, como Bash:
```bash
cd directorio
```
```bash
ls
```
```bash
pwd
```
```bash
mkdir nombre_directorio
```
```bash
rm archivo
rm -r directorio
```
```bash
cp origen destino
```
```bash
mv origen destino
```
```bash
cat archivo
```
9. **echo**: Imprimir texto en la pantalla.
```bash
echo "texto"
```
```bash
```
```bash
```
```bash
```
```bash
ps
```
```bash
kill PID
```
```bash
man comando
```
Estos son solo algunos de los comandos básicos disponibles en una shell. Hay muchos
más comandos y opciones que pueden ser útiles dependiendo de tus necesidades y del entorno en
el que estés trabajando.
Condicionales y ciclos
En el scripting de shell (como en Bash), los condicionales y los bucles son fundamentales
para controlar el flujo de ejecución del programa. Aquí te muestro cómo puedes usar
condicionales y bucles en Bash:
Condicionales:
1. If-else:
```bash
if [ condición ]; then
# Código si la condición es verdadera
else
# Código si la condición es falsa
fi
```
Ejemplo:
```bash
edad=18
if [ "$edad" -ge 18 ]; then
echo "Eres mayor de edad"
else
echo "Eres menor de edad"
fi
```
2. If-elif-else:
```bash
if [ condición1 ]; then
# Código si la condición1 es verdadera
elif [ condición2 ]; then
# Código si la condición2 es verdadera
else
# Código si todas las condiciones son falsas
fi
```
Bucles:
1. For loop:
```bash
for variable in lista_de_elementos; do
# Código a ejecutar
done
```
Ejemplo:
```bash
for archivo in *.txt; do
echo "Procesando archivo: $archivo"
done
```
2. While loop:
```bash
while [ condición ]; do
# Código a ejecutar mientras la condición sea verdadera
done
```
Ejemplo:
```bash
contador=1
while [ $contador -le 5 ]; do
echo "Contador: $contador"
contador=$((contador+1))
done
```
3. Until loop:
```bash
until [ condición ]; do
# Código a ejecutar mientras la condición sea falsa
done
```
Ejemplo:
```bash
contador=1
until [ $contador -gt 5 ]; do
echo "Contador: $contador"
contador=$((contador+1))
done
```
Estos son solo algunos ejemplos básicos de cómo usar condicionales y bucles en Bash.
Puedes combinarlos y anidarlos según sea necesario para construir scripts más complejos y
funcionales.
Estructuras de control
En Bash, al igual que en otros lenguajes de programación, las estructuras de control
permiten controlar el flujo de ejecución de un script. Las principales estructuras de control en
Bash son los condicionales (`if-else`), los bucles (`for`, `while`, `until`) y la instrucción `case`.
Aquí tienes una descripción de cada una:
1. Condicionales (if-else):
```bash
if [ condición ]; then
# Código a ejecutar si la condición es verdadera
else
# Código a ejecutar si la condición es falsa
fi
```
2. Bucles:
a. For loop:
```bash
for variable in lista_de_elementos; do
# Código a ejecutar en cada iteración
done
```
b. While loop:
```bash
while [ condición ]; do
# Código a ejecutar mientras la condición sea verdadera
done
```
c. Until loop:
El bucle `until` es similar al bucle `while`, pero se ejecuta mientras la condición sea falsa.
```bash
until [ condición ]; do
# Código a ejecutar mientras la condición sea falsa
done
```
3. Instrucción case:
La instrucción `case` se utiliza para realizar diferentes acciones dependiendo del valor de
una variable.
```bash
case $variable in
valor1)
# Código a ejecutar si la variable es igual a
valor1
;;
valor2)
# Código a ejecutar si la variable es igual a
valor2
;;
*)
# Código a ejecutar si la variable no coincide con
ninguno de los valores anteriores
;;
esac
```
Ejemplo combinando varias estructuras de control:
```bash
#!/bin/bash
# Estructura de control combinando condicional y bucle
contador=1
while [ $contador -le 5 ]; do
if [ $contador -eq 3 ]; then
echo "El contador es igual a 3"
else
echo "El contador no es igual a 3"
fi
contador=$((contador+1))
done
```
Estas son las principales estructuras de control en Bash que te permiten escribir scripts
poderosos y flexibles para automatizar tareas en sistemas Unix/Linux.
Operaciones algebraicas
Puedes realizar operaciones algebraicas en Bash utilizando la herramienta `bc`
(calculadora de precisión arbitraria). `bc` es una calculadora de precisión arbitraria que permite
realizar cálculos matemáticos básicos y avanzados en la línea de comandos. Aquí tienes un
ejemplo de cómo realizar operaciones algebraicas básicas en Bash utilizando `bc`:
```bash
#!/bin/bash
# Operaciones algebraicas en Bash utilizando bc
# Suma
echo "Suma:"
echo "5 + 3" | bc
# Resta
echo "Resta:"
echo "8 - 2" | bc
# Multiplicación
echo "Multiplicación:"
echo "4 * 6" | bc
# División
echo "División:"
echo "12 / 4" | bc
# Potencia
echo "Potencia:"
echo "2 ^ 3" | bc
# Raíz cuadrada
echo "Raíz cuadrada:"
echo "sqrt(16)" | bc
# Operaciones con decimales
echo "Operaciones con decimales:"
echo "scale=2; 5 / 3" | bc
```
Este script realizará varias operaciones algebraicas básicas utilizando `bc`. Puedes
ejecutarlo en la línea de comandos de tu terminal Bash y verás los resultados. Además, puedes
ajustar la precisión decimal con `scale=n` donde `n` es el número de decimales que deseas
mostrar en el resultado.
```bash
#!/bin/bash
Luego, puedes ejecutar este script desde la línea de comandos y pasarle argumentos como
sigue:
```bash
./mi_script.sh argumento1 argumento2
```
En este ejemplo:
Puedes usar `$#` para obtener el número total de argumentos pasados al script. Por
ejemplo:
```bash
echo "Número total de argumentos: $#"
```
Valor de retorno
En Bash, al final de un script o de un comando ejecutado dentro de un script, puedes
especificar un valor de retorno utilizando la palabra clave `return`. El valor de retorno es un
número entero que indica si la ejecución del script o del comando fue exitosa o no. Por
convención, un valor de retorno de `0` indica éxito, mientras que cualquier otro valor distinto de
`0` indica algún tipo de error.
Aquí hay un ejemplo simple de cómo puedes usar `return` en un script de Bash:
```bash
#!/bin/bash
En este caso, el script imprimirá "10 es un número par." porque `10` es un número par y
la función `es_par` devuelve `0`, indicando éxito.
Evaluar expresiones
En Bash, puedes evaluar expresiones aritméticas utilizando el comando `expr` o la doble
paréntesis `(( ... ))`. Aquí te muestro ambos métodos:
1. **Usando `expr`**:
```bash
#!/bin/bash
# Evaluar expresiones aritméticas con expr
# Definir las expresiones
expresion1="3 + 5"
expresion2="10 - 2"
expresion3="2 * 4"
expresion4="20 / 5"
```bash
#!/bin/bash
# Mostrar resultados
echo "Resultado de 3 + 5: $expresion1"
echo "Resultado de 10 - 2: $expresion2"
echo "Resultado de 2 * 4: $expresion3"
echo "Resultado de 20 / 5: $expresion4"
```
Ambos métodos funcionan para evaluar expresiones aritméticas en Bash. Sin embargo,
ten en cuenta que `(( ... ))` es más flexible y puede manejar expresiones más complejas, además
de admitir asignaciones y comparaciones.
1. **Cadenas (Strings)**:
Las cadenas son secuencias de caracteres. En Bash, las cadenas pueden ser definidas
utilizando comillas simples (`'...'`) o comillas dobles (`"..."`). Las comillas dobles permiten la
expansión de variables y caracteres de escape, mientras que las comillas simples no.
Ejemplo:
```bash
cadena1="Hola, mundo!"
cadena2='Este es un ejemplo'
```
2. **Números (Numbers)**:
Los números en Bash son tratados como cadenas por defecto, pero pueden ser
interpretados como enteros o números de punto flotante en contextos aritméticos utilizando la
expresión `(( ... ))` o la herramienta `expr`.
Ejemplo:
```bash
numero1=10
numero2="20"
```
3. **Arreglos (Arrays)**:
Los arreglos en Bash permiten almacenar múltiples valores en una sola variable. Se
definen utilizando paréntesis `(...)` y los elementos se separan por espacios.
Ejemplo:
```bash
mi_array=("valor1" "valor2" "valor3")
```
4. **Variables Especiales**:
Bash tiene varias variables especiales que almacenan información útil. Algunas de estas
incluyen:
5. **Booleanos (Booleans)**:
Bash no tiene un tipo de dato booleano nativo, pero los valores `true` y `false` se
pueden representar usando convenciones numéricas. Por ejemplo, `0` puede representar `false` y
cualquier otro valor puede representar `true`.
Ejemplo:
```bash
verdadero=1
falso=0
```
6. **Nulo (Null)**:
No existe un tipo de dato `null` específico en Bash. Sin embargo, una variable no
inicializada o vacía puede considerarse nula.
Es importante tener en cuenta que en Bash, las variables no tienen un tipo de dato fijo; el
tipo de dato de una variable puede cambiar dinámicamente según el contexto en el que se utilice.
Esto permite una gran flexibilidad pero también puede llevar a comportamientos inesperados si
no se tiene cuidado.
Operadores booleanos
En Bash, puedes utilizar operadores booleanos para realizar comparaciones y
evaluaciones lógicas en tus scripts. Aquí tienes una lista de los operadores booleanos más
comunes en Bash:
```bash
if [ "$cadena1" == "$cadena2" ]; then
echo "Las cadenas son iguales."
fi
```
2. **Operador de No igual (`!=`)**:
```bash
if [ "$cadena1" != "$cadena2" ]; then
echo "Las cadenas son diferentes."
fi
```
```bash
if [ "$numero1" -eq "$numero2" ]; then
echo "Los números son iguales."
fi
```
4. **Operadores Lógicos**:
```bash
if [ "$condicion1" -eq 1 ] && [ "$condicion2" -eq 2 ];
then
echo "Ambas condiciones son verdaderas."
fi
Puedes habilitar el modo de depuración agregando `set -x` al principio de tu script. Esto
mostrará cada línea de tu script mientras se ejecuta, lo que puede ayudarte a identificar dónde
ocurren los errores.
```bash
#!/bin/bash
set -x
# Resto de tu script aquí
```
2. Agrega `echo` Statements
```bash
#!/bin/bash
echo "Iniciando ejecución del script..."
# Resto de tu script aquí
```bash
#!/bin/bash
set -e
# Resto de tu script aquí
```
4. Maneja Errores con `if` Statements y `exit`
Utiliza declaraciones `if` para verificar el resultado de los comandos críticos y usa
`exit` para salir del script si es necesario.
```bash
if ! [ -f "$archivo" ]; then
echo "Error: El archivo no existe."
exit 1
fi
```
Errores Comunes en Bash:
1. **Errores de Sintaxis**:
Intentar ejecutar un comando que requiere permisos especiales sin tenerlos puede
causar errores.
5. **Errores Lógicos**:
Al depurar scripts Bash, ten en cuenta que los mensajes de error a menudo pueden ser
crípticos, así que no dudes en experimentar con diferentes técnicas de debugging y buscar ayuda
en la documentación y en línea.
Aquí hay algunos ejemplos de "Bashismos" comunes y cómo podrían no ser compatibles
con POSIX:
1. Construcciones de Arreglos Asociativos:
Bash admite arreglos asociativos, que permiten asociar claves de cadena con valores.
Este es un Bashismo porque no está presente en otros shells de Unix y no es parte del estándar
POSIX.
Bash admite `[[ ... ]]` para pruebas de condición más avanzadas y flexibles, pero esto no
es parte del estándar POSIX. Para scripts portables, es mejor usar `[ ... ]` para pruebas de
condición.
Bash tiene la variable especial `$RANDOM` para generar números aleatorios, pero esta
funcionalidad no está garantizada en otros shells de Unix.
Usando SHC
`SHC` es una utilidad de línea de comandos que se utiliza para compilar scripts de shell
(como scripts Bash) en binarios ejecutables. Esto puede ser útil para proteger el código fuente del
script y para distribuirlo en entornos donde no deseas que el código sea fácilmente legible o
editable.
Aquí podemos ver una breve guía sobre cómo usar `SHC`:
1. Instalación:
```bash
shc -f mi_script.sh
```
Esto generará un archivo ejecutable llamado `mi_script.sh.x`. Este archivo es el binario
compilado del script original.
```bash
./mi_script.sh.x
```
El script se ejecutará como lo haría normalmente, pero ahora está compilado en forma
binaria.
Es importante tener en cuenta que `SHC` no proporciona una seguridad completa para tu
código fuente, ya que el binario compilado aún puede ser descompilado. Sin embargo, puede
dificultar la edición casual del script y puede proporcionar cierta protección contra la
visualización del código fuente a simple vista.
Además, ten en cuenta que `SHC` tiene algunas limitaciones y puede no ser compatible
con todos los scripts de shell, especialmente aquellos que utilizan características avanzadas de
Bash o dependencias externas. Es recomendable realizar pruebas exhaustivas después de
compilar un script con `SHC` para asegurarse de que funcione como se espera.
Python es un lenguaje de programación versátil y potente que se integra bien con Bash.
Puedes ejecutar comandos de Python directamente desde un script de Bash utilizando el
intérprete de Python. Esto te permite aprovechar las bibliotecas y capacidades avanzadas de
Python mientras mantienes la flexibilidad de Bash para realizar tareas de administración del
sistema.
```bash
#!/bin/bash
# Ejecutar un script de Python desde Bash
python3 mi_script.py
```
2. Bash con Perl:
Perl es otro lenguaje de scripting popular que se puede combinar fácilmente con Bash.
Al igual que con Python, puedes ejecutar scripts de Perl directamente desde un script de Bash.
```bash
#!/bin/bash
Ruby es otro lenguaje de scripting que se puede integrar con Bash. Puedes ejecutar
scripts de Ruby desde un script de Bash de manera similar a Python y Perl.
```bash
#!/bin/bash
Sed es otra herramienta útil para el procesamiento de texto que se puede integrar con
Bash. Puedes usar Sed directamente desde un script de Bash para realizar sustituciones de texto y
otras manipulaciones.
```bash
#!/bin/bash
PowerShell utiliza cmdlets (command-lets) para realizar tareas específicas. Los cmdlets
siguen un formato de verbo-sustantivo y proporcionan una funcionalidad modular y reutilizable.
```powershell
Get-Process
```
3. Parámetros de Cmdlets:
```powershell
Get-Help Get-Process
```
4. `Get-Help`:
`Get-Help` es un cmdlet en PowerShell que te proporciona información detallada sobre
otros cmdlets, funciones, módulos y scripts disponibles en PowerShell. Puedes usar `Get-Help`
para obtener descripciones, ejemplos de uso, sintaxis de comando y más.
```powershell
# Obtener ayuda sobre un cmdlet específico
Get-Help Get-Process
PowerShell admite alias de comandos, que son abreviaturas o nombres alternativos para
cmdlets, funciones y scripts. Puedes usar `Get-Alias` para obtener una lista de alias definidos en
PowerShell.
```powershell
# Obtener una lista de alias definidos en PowerShell
Get-Alias
```
6. Tab Completions:
```powershell
# Presionar la tecla de tabulación para completar
automáticamente nombres de cmdlets, parámetros, etc.
Get-P<tab>
```
`Get-Help` es una herramienta muy útil en PowerShell para familiarizarse con los
cmdlets disponibles, aprender sobre sus funcionalidades y obtener ayuda en tiempo real mientras
trabajas en el shell. Es una práctica recomendada consultar la ayuda antes de utilizar nuevos
cmdlets para comprender mejor su uso y funcionalidad.
Set-ExecutionPolicy.
`Set-ExecutionPolicy` es un cmdlet de PowerShell que se utiliza para establecer la
política de ejecución de scripts en un entorno de PowerShell. Esta política determina qué scripts
pueden ejecutarse en el sistema y puede ayudar a prevenir la ejecución no autorizada de scripts
maliciosos.
```powershell
Set-ExecutionPolicy <Policy>
```
Donde `<Policy>` puede ser uno de los siguientes valores:
¿Qué es el Pipeline?
El "pipeline" en PowerShell se refiere a la capacidad de encadenar múltiples cmdlets
(comandos) juntos, donde la salida de uno se convierte automáticamente en la entrada del
siguiente. Esto permite realizar operaciones complejas y encadenadas de manera eficiente con
una sola línea de comando.
Por ejemplo, supongamos que queremos obtener una lista de los procesos en ejecución
que están utilizando más memoria en el sistema y luego ordenarlos por la cantidad de memoria
utilizada. Podemos hacerlo utilizando el pipeline en PowerShell de la siguiente manera:
```powershell
Get-Process | Sort-Object -Property WS | Select-Object -
Last 10
```
En este ejemplo:
- `Get-Process` obtiene una lista de todos los procesos en ejecución en el sistema.
- La salida de `Get-Process` se pasa automáticamente al cmdlet `Sort-Object`, que
ordena los procesos en función de la cantidad de memoria que están utilizando (`WS`
representa la propiedad de memoria de trabajo).
- La salida de `Sort-Object` se pasa al cmdlet `Select-Object`, que selecciona los
últimos 10 procesos de la lista ordenada.
El resultado final es una lista de los 10 procesos que están utilizando más memoria en el
sistema, ordenados de mayor a menor.
El uso del pipeline en PowerShell es una característica poderosa que permite realizar
tareas complejas y realizar análisis de datos de manera eficiente y concisa. Permite a los usuarios
combinar y manipular datos de manera flexible para obtener los resultados deseados.
```powershell
# Importar contenido de un archivo de texto línea por línea
Get-Content -Path "archivo.txt"
```
2. Importar desde un archivo CSV:
```powershell
# Importar datos desde un archivo CSV
Import-Csv -Path "archivo.csv"
```
3. Importar desde una hoja de cálculo de Excel:
```powershell
# Instalar el módulo ImportExcel (solo es necesario la
primera vez)
Install-Module ImportExcel -Scope CurrentUser -Force
```powershell
# Instalar el módulo SqlServer (solo es necesario la
primera vez)
Install-Module SqlServer -Force -AllowClobber
```powershell
# Utilizar Invoke-RestMethod para hacer una solicitud GET a
un servicio web que devuelve datos en formato JSON
$response = Invoke-RestMethod -Uri
"https://api.example.com/data" -Method Get
```powershell
# Exportar datos a un archivo CSV
$data | Export-Csv -Path "archivo.csv" -NoTypeInformation
```
3. Exportar a una hoja de cálculo de Excel:
```powershell
# Instalar el módulo ImportExcel (solo es necesario la primera
vez)
Install-Module ImportExcel -Scope CurrentUser -Force
```powershell
# Instalar el módulo SqlServer (solo es necesario la primera
vez)
Install-Module SqlServer -Force -AllowClobber
# Cerrar la conexión
$conn.Close()
```
5. Exportar a un servicio web (por ejemplo, JSON):
```powershell
# Convertir los datos a formato JSON
$jsonData = $data | ConvertTo-Json
Comentarios y variables
Por supuesto, en PowerShell puedes usar comentarios para hacer tu código más legible y
mantener notas para ti mismo o para otros que puedan leer tu código en el futuro. También
puedes definir y utilizar variables para almacenar valores y realizar operaciones. Aquí te muestro
cómo puedes hacer ambas cosas en PowerShell:
Comentarios en PowerShell:
Los comentarios en PowerShell se crean utilizando el símbolo `#`. Todo lo que escribas
después de `#` en una línea será tratado como un comentario y no se ejecutará.
```powershell
# Esto es un comentario en PowerShell
Variables en PowerShell:
En PowerShell, las variables se definen con el prefijo `$`. Puedes asignarles valores
directamente y utilizarlas en tu script.
```powershell
# Definir una variable llamada $nombre y asignarle un valor
$nombre = "Juan"
# Imprimir el valor de la variable $nombre
Write-Output $nombre
```
Las variables en PowerShell son tipadas dinámicamente, lo que significa que el tipo de
datos de la variable puede cambiar automáticamente según el tipo de valor que le asignes.
```powershell
# Asignar un valor numérico a la variable $edad
$edad = 30
```powershell
# Definir un arreglo de nombres
$nombres = @("Juan", "María", "Pedro")
1. `$PSVersionTable`:
```powershell
# Mostrar información sobre la versión de PowerShell
$PSVersionTable
```
2. `$MyInvocation`:
Esta variable proporciona información sobre la invocación actual del script, incluido el
nombre del script, los parámetros pasados al script y la ruta del script.
```powershell
# Mostrar información sobre la invocación actual del script
$MyInvocation
```
3. `$PSCmdlet`:
```powershell
# Mostrar información sobre el contexto del cmdlet
$PSCmdlet
```
4. `$ExecutionContext`:
```powershell
# Mostrar información sobre el contexto de ejecución actual
$ExecutionContext
```
5. `$Error`:
Esta variable contiene una lista de todos los errores que se han producido durante la
ejecución del script actual.
```powershell
# Mostrar una lista de errores
$Error
```
6. `$Host`:
Esta variable proporciona acceso al objeto host actual, que puede utilizarse para
interactuar con el entorno de PowerShell, como cambiar el color de la consola o mostrar
mensajes al usuario.
```powershell
# Mostrar información sobre el host actual
$Host
```
Estas son solo algunas de las variables predefinidas disponibles en PowerShell. Puedes
usar estas variables para acceder a información útil sobre el entorno de ejecución y el contexto de
ejecución actual, lo que puede ser útil para la depuración, el registro y otras tareas de
administración de scripts.
Constantes
En PowerShell, no hay un concepto directo de "constantes" como en otros lenguajes de
programación, donde una constante es un valor que no cambia durante la ejecución del
programa. Sin embargo, puedes simular constantes utilizando variables que no cambien de valor
durante la ejecución del script y convenciones de nomenclatura para indicar que una variable se
trata como una constante.
Puedes usar convenciones de nomenclatura para indicar que una variable debe tratarse
como una constante. Por ejemplo, puedes nombrar tus variables en mayúsculas para indicar que
son constantes y no deben cambiar.
```powershell
# Definir una constante
$CONSTANTE = "valor constante"
# Usar la constante
Write-Output $CONSTANTE
```
2. Definir variables en el script principal:
Puedes definir tus "constantes" al principio del script principal y luego usarlas en todo el
script. Aunque las variables pueden cambiar su valor durante la ejecución del script, es una
práctica común no modificarlas.
```powershell
# Definir constantes
$CONSTANTE1 = "valor constante 1"
$CONSTANTE2 = "valor constante 2"
Puedes definir funciones que devuelvan valores constantes y luego llamar a esas
funciones cuando necesites usar las constantes en tu script.
```powershell
# Definir una función que devuelve una constante
function Get-CONSTANTE {
return "valor constante"
}