Programacion BASH
Programacion BASH
#!/bin/bash
echo Hola Mundo
Este script tiene sólo dos líneas. La primera le indica al sistema qué
programa usar para ejecutar el fichero.
La segunda línea es la única acción realizada por este script, que imprime
'Hola Mundo' en la terminal.
#!/bin/bash
tar -cZf /var/my-backup.tgz /home/yo/
ls -l > ls-l.txt
grep da * 1>&2
En este caso, la parte stdout del comando se envía a stderr; puede observar
eso de varias maneras.
grep * 2>&1
En este caso, la parte stderr del comando se envía a stdout. Si hace una
tubería con less, verá que las líneas que normalmente 'desaparecen' (al ser
escritas en stderr), ahora permanecen (porque están en el stdout).
Tuberías
Esta sección explica de una manera muy sencilla y práctica cómo utilizar
tuberías, y por qué querría utilizarlas.
Variables
Puede usar variables como en cualquier otro lenguaje de programación. No
existen tipos de datos. Una variable de bash puede contener un número, un
caracter o una cadena de caracteres.
La segunda línea crea una variable llamada STR y le asigna la cadena "¡Hola
Mundo!". Luego se recupera el VALOR de esta variable poniéndole un '$' al
principio. Por favor, tenga en cuenta (¡inténtelo!) que si no usa el signo '$',
la salida del programa será diferente, y probablemente no sea lo que usted
quería.
#!/bin/bash
OF=/var/mi-backup-$(date +%Y%m%d).tgz
tar -cZf $OF /home/yo/
Este script introduce algo nuevo. Antes que nada, debería familiarizarse con
la creación y asignación de variable de la línea 2. Fíjese en la expresión '$
(date +%Y%m%d)'. Si ejecuta el script se dará cuenta de que ejecuta el
comando que hay dentro de los paréntesis, capturando su salida.
Tenga en cuenta que en este script, el fichero de salida será distinto cada
día, debido al formato pasado al comando date (+%Y%m%d). Puede cambiar
esto especificando un formato diferente.
echo ls
echo $(ls)
Este ejemplo debería bastar para mostrarle el uso de una variable local.
Estructuras Condicionales
Las estructuras condicionales le permiten decidir si se realiza una acción o
no; esta decisión se toma evaluando una expresión.
if [expresión];
then
fi
#!/bin/bash
if [ "petete" = "petete" ]; then
echo expresión evaluada como verdadera
else
echo expresión evaluada como falsa
fi
#!/bin/bash
T1="petete"
T2="peteto"
if [ "$T1" = "$T2" ]; then
echo expresión evaluada como verdadera
else
echo expresión evaluada como falsa
fi
#!/bin/bash
FILE=~/.basrc
if [ -f $FILE ]; then
echo el fichero $FILE existe
else
echo fichero no encontrado
fi
if [ 'test -f $FILE']
Los bucles for, while y until
En esta sección se encontrará con los bucles for, while y until.
#!/bin/bash
for i in $( ls ); do
echo item: $i
done
La tercera línea podría ser más larga o podría haber más líneas antes del
done (4).
Este script no tiene mucho sentido, pero una manera más útil de usar el
bucle for sería hacer que concordasen sólo ciertos ficheros en el ejemplo
anterior.
#!/bin/bash
for i in `seq 1 10`;
do
echo $i
done
#!/bin/bash
CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
echo El contador es $CONTADOR
let CONTADOR=CONTADOR+1
done
Este script 'emula' la conocida (C, Pascal, perl, etc) estructura `for'.
#!/bin/bash
CONTADOR=20
until [ $CONTADOR -lt 10 ]; do
echo CONTADOR $CONTADOR
let CONTADOR-=1
done
Funciones
Como en casi todo lenguaje de programación, puede utilizar funciones para
agrupar trozos de código de una manera más lógica, o practicar el divino
arte de la recursión.
Llamar a la función es como llamar a otro programa, sólo hay que escribir su
nombre.
Las líneas 2-4 contienen la función 'salir'. Las líneas 5-7 contienen la función
'hola'. Si no está completamente seguro de lo que hace este script, por
favor, ¡pruébelo!.
Tenga en cuenta que una función no necesita que sea declarada en un orden
específico.
#!/bin/bash
function salir {
exit
}
function e {
echo $1
}
e Hola
e Mundo
salir
echo petete
Interfaces de usuario
9.1 Utilizando select para hacer menús sencillos
#!/bin/bash
OPCIONES="Hola Salir"
select opt in $OPCIONES; do
if [ "$opt" = "Salir" ]; then
echo done
exit
elif [ "$opt" = "Hola" ]; then
echo Hola Mundo
else
clear
echo opción errónea
fi
done
Lo que hace este script debería estar claro para usted. La expresión del
primer condicional comprueba si el programa ha recibido algún argumento
($1) y sale si no lo ha recibido, mostrándole al usuario un pequeño mensaje
de uso. El resto del script debería estar claro.
Miscelánea
#!/bin/bash
echo Por favor, introduzca su nombre
read NOMBRE
echo "¡Hola $NOMBRE!"
Como variante, se pueden obtener múltiples valores con read. Este ejemplo
debería clarificarlo.
#!/bin/bash
echo Por favor, introduzca su nombre y primer apellido
read NO AP
echo "¡Hola $AP, $NO!"
Si esperaba ver '2', quedará desilusionado. ¿Qué hacer si quiere que BASH
evalúe unos números? La solución es ésta:
echo $((1+1))
Esto producirá una salida más 'lógica'. Esto se hace para evaluar una
expresión aritmética. También puede hacerlo de esta manera:
echo $[1+1]
tienen locate.
normalmente.
ls -l /bin/bash
ls -l /sbin/bash
ls -l /usr/local/bin/bash
ls -l /usr/bin/bash
ls -l /usr/sbin/bash
ls -l /usr/local/sbin/bash
#!/bin/bash
cd /dada &> /dev/null
echo rv: $?
cd $(pwd) &> /dev/null
echo rv: $?
Este pequeño script muestra todas las tablas de todas las bases de datos
(suponiendo que tenga MySQL instalado). Considere también cambiar el
comando 'mysql' para que use un nombre de usuario y clave válidos.
#!/bin/bash
DBS=`mysql -uroot -e"show databases"`
for b in $DBS ;
do
mysql -uroot -e"show tables from $b"
done
Tablas
11.1 Operadores de comparación de cadenas
s1 = s2
s1 coincide con s2
s1 != s2
s1 no coincide con s2
s1 < s2
s1 es alfabéticamente anterior a s2, con el locale actual
s1 > s2
s1 es alfabéticamente posterior a s2, con el locale actual
-n s1
s1 no es nulo (contiene uno o más caracteres)
-z s1
s1 es nulo
#!/bin/bash
S1='cadena'
S2='Cadena'
if [ $S1!=$S2 ];
then
echo "S1('$S1') no es igual a S2('$S2')"
fi
if [ $S1=$S1 ];
then
echo "S1('$S1') es igual a S1('$S1')"
fi
Esto no es buena idea, porque si $S1 o $S2 son vacíos, aparecerá un parse
error. Es mejor: x$1=x$2 or "$1"="$2"
- (sustracción)
* (producto)
/ (división)
% (módulo)
-gt (>)
-le (<=)
-ge (>=)
-eq (==)
-ne (!=)
"prueba123
prueba
pprruueebbaa"
y ejecutamos:
test123
test
Ya hemos visto ejemplos del comando grep en los capítulos anteriores, que
muestra las líneas que concuerdan con un patrón. Pero grep puede hacer
más que eso.
12
Se ha encontrado 12 veces la cadena "busca esto" en el fichero
/var/log/messages.
"programación en bash
como de introducción"
2 5 41 /tmp/petete
"b
c
a"
$sort /tmp/petete
a
b
c
$bc -q
1 == 5
0.05 == 0.05
5 != 5
2^8
256
sqrt(9)
while (i != 9) {
i = i + 1;
print i
123456789
quit
$tput cup 10 4
La línea de comandos aparece en (y10,x4).
$tput reset
$tput cols
80
Muestra el número de caracteres que caben en la dirección x.
Más scripts
12.1 Aplicando un comando a todos los ficheros de un directorio.
#!/bin/bash
ORIG="/home/"
DEST="/var/copias_de_seguridad/"
FICH=home-$(date +%Y%m%d).tgz
tar -cZf $DEST$FICH $ORIG
#!/bin/sh
# renom: renombra múltiples ficheros de acuerdo con ciertas
# si la primera ($1) condición coincide, se ejecuta esa parte
#del programa y acaba
#comprueba la condición de prefijo
if [ $1 = p ]; then
# ahora nos libramos de la variable de modo ($1) y ponemos $2
# de prefijo
prefijo=$2 ; shift ; shift
if [$1 = ]; then
echo "no se especificaron ficheros"
exit 0
fi
for fichero in $*
do
mv ${fichero} $fichero$sufijo
done
exit 0
fi
shift
# hecho!
#!/bin/bash
# renombra.sh
# renombrador de ficheros básico
criterio=$1
expresion=$2
sustituto=$3
for i in $( ls *$criterio* );
do
orig=$i
dest=$(echo $i | sed -e "s/$expresion/$sustituto/")
mv $orig $dest
done
Cuando algo va mal (depuración)
#!/bin/bash -x