Las historias de Zenon

  • RSS Alguien no quiere que leamos esto

    • Ha ocurrido un error; probablemente el feed está caído. Inténtalo de nuevo más tarde.
  • Historial

    mayo 2007
    L M X J V S D
    « Mar   Jun »
     123456
    78910111213
    14151617181920
    21222324252627
    28293031  
  • Mis enlaces en del.icio.us

  • Meta

  • Pobreza cero

  • Cultura Libre

    Cultura Libre
  • Linux Counter


    The Ubuntu Counter Project - user number # 3747
  • Licencia

    El contenido de esta bitácora se encuentra protegido bajo la licencia Reconocimiento - CompartirIgual de Creative Commons.
    Reconocimiento y Compartir igual

    © Jose Luis Jimenez, Getafe 2006
    Los comentarios son responsabilidad exclusiva de los autores de los mismos.

Aventurandose por los shell scripts

Posted by Jose Luis en 11 mayo 2007

En esta anotación voy a intentar dar unas breves ideas para aquellos que quieran hacer sus primeros pinitos en la programación de shell scripts.

La shell utilizada será bash pues además de ser la que se utiliza por defecto en GNU/Linux es también la más potente, al menos de las que conozco, csh, ksh y bash.

Un shell script no es más que un fichero que contiene un conjunto de comandos y que puede ser ejecutado desde un terminal.

Cuando se ejecuta un shell script realmente lo que se hace es lanzar una shell (bash, ksh, csh o la que sea) que se encarga de interpretar y ejecutar las órdenas contenidas en el fichero del script.

Para ejecutar un script se puede hacer de varias maneras:

  • Dandole permisos de ejecución y lanzarlo escribiendo el path donde se encuentra y el nombre. Por ejemplo si tenemos un script que se llama sx99 y que se encuentra en el directorio /opt/scripts para lanzarlo (una vez dados los permisos de ejecución) tendrías que hacer:
    /opt/scripts/sx99
  • Dandole permisos de ejecución y situarlo en alguno de los directorios de la variable PATH (por ejemplo en /usr/local/bin). Es similar al anterior pero para lanzarlo no hay que poner la ruta de donde se encuentra ya que es suficiente con poner su nombre
  • Lanzando explícitamente la shell y pasandoe por parámetro el script (no son necesarios permisos de ejecución). En el ejemplo anterior:
    bash /opt/scripts/sx99

La primera línea que se suele poner en un script (no es obligatoria) es una línea que le indica al sistema cuál es el intérprete que debe utilizar para ejecutar nuestro script (si no se pone nada utilizará el shell por defecto que como hay he mencionado suele ser bash).

#!/bin/bash

En este caso se está indicando que el intérprete será bash y que está ubicado (bash) en /bin.
Si por ejemplo nuestro script fuera para ksh y ksh se encontrara en /usr/bin deberiamos poner en la primera línea:

#!/usr/bin/ksh

Cuando se quieren añadir comentarios, es decir líneas en el fichero de script que el intérprete debe ignorar se preceden por el carácter #

# Lanzo el comando ls con el parámetro -l
ls -l

Si queremos asignar valores a variables lo haremos mediante el = pero teniendo cuidado de no dejar ningun espacio entre el = y el nombre de la variable y el = y el valor que le damos.

# Así no
otravariable = 1
# Así sí
variable=1

Para acceder al valor contenido en otra variable utilizaremos el $ delante del nombre de la variable (es una práctica recomendable utilizar el nombre de la variable encerrado entre {})

# Esto muestra por la salida estandar, 
# en principio la pantalla, el valor de variable
echo $variable
# Esto tambien pero a mi me gusta mas que la anterior
echo ${variable}

Si después de ejecutar un comando queremos comprobar si ha ido mal podemos utilizar $? inmediatamente después de ejecutar el comando. Si no es 0 es que algo ha ido mal.

# Esta ejecucion ira bien y por tanto mostrara un 0
ls -l
echo $?
# Esta ejecucion ira mal (siempre que no exista un fichero 
# llamado dsafhjsdf) y mostrara un valor distinto de 0
ls -l dsafhjsdf
echo $?

Si queremos preguntar por alguna variable para hacer o no hacer algo utilizaremos la sentencia if

ls -l dsafhjsdf
retorno=$?
if [ ${retorno} -ne 0 ]; then
echo "Ha dado el error ${retorno} la ejecucion de ls -l dsafhjsdf"
else
echo "Ha ido bien la ejecucion de ls -l dsafhjsdf"
fi

Hay que darse cuenta que un if se cierra con un fi, que puede tener un else y que la condición va entre []. Es necesario que después del [ y antes del ] debe existir al menos un espacio. El ; que va entre el ] y el then no es necesario pero si no se pone la palabra then debe ir en la siguiente línea.

ls -l dsafhjsdf
retorno=$?
if [ ${retorno} -ne 0 ]
then
echo "Ha dado el error ${retorno} la ejecucion de ls -l dsafhjsdf"
else
echo "Ha ido bien la ejecucion de ls -l dsafhjsdf"
fi

Si lo que se van a comparar son números (como en el ejemplo), para comparar se utiliza lo siguiente:

  • -eq -> igual
  • -ne -> distinto
  • -lt -> menor
  • -le -> menor o igual
  • -gt -> mayor
  • -ge -> mayor o igual

Mientras que si lo que se van a comparar son textos lo que se utiliza es:

  • = -> igual
  • == -> igual (como el anterior aunque yo prefiero esta sintaxis que es la de C para diferenciarlo de la asignacion)
  • != -> distinto

En el caso de la comparación de textos conviene utilizar las variables encerradas entre “”

nombre="Pedro"
if [ "${nombre}" == "Antonio" ]; then
echo Es Antonio
else
echo No es Antonio, es ${nombre}
fi

Si una variable no está definida o está vacía se puede detectar utilizando la opción -z dentro del if:

if [ -z ${apellido} ]; then
echo La variable apellido no existe o no tiene valor
else
echo El apellido es ${apellido}
fi

En ocasiones querremos repetir algo, por ejemplo convertir de formato todas las imágenes jpg de un directorio y pasarlas a png:

for i in *.jpg ; do
convert "${i}" "`echo $i | sed "s/.jpg$/.png/g`"
done

En este caso mediante *.jpg sacamos una lista de los archivos del directorio en el que se ejecute que terminan en .jpg, la variable i va tomando en cada iteración del bucle el nombre de cada uno de estos archivos.
Luego utilizamos la utilidad convert para pasar del jpg a png y para ello le pasamos como primer parámetro el fichero jpg (${i}) encerrado además entre “” para evitar problemas con los espacios que pueda tener el nombre y utilizamos sed para construir el segundo parámetro que tendrá el mismo nombre que el fichero jpg pero cambiando jpg por png.
Además utilizamos los acentos graves (`) para que al ejecutar un determinado comando nos asigne su salida a una variable o como en el ejemplo lo ponga en el segundo parámetro del convert. Si por ejemplo hubieramos querido guardar el nombre del nuevo fichero png en otra variable deberiamos hacer:

nombre_del_png=`echo $i | sed "s/.jpg$/.png/g`

o también se podría hacer sin utilizar el acento con:

nombre_del_png=$(echo $i | sed "s/.jpg$/.png/g)

También nos puede interesar, hay gente para todo😉, sacar los n primeros números de la serie de Fibonacci (esa que empieza por 1 1 2 3 5 8 13 21 34 … y que tiene algo que ver con la capacidad reproductora de los conejos).
Para ello podemos utilizar el bucle while y algunos otros apaños:

max=10
n_2=1
n_1=1
echo 1 - ${n_2}
echo 2 - ${n_1}
i=3
while [ ${i} -le ${max} ]; do
n=$((${n_2} + ${n_1}))
n_2=${n_1}
n_1=${n}
echo ${i} - ${n}
i=$((${i}+1))
done

En este caso utilizamos while para montar un bucle que se ejecutará mientras que se cumpla la condición, en el ejemplo lo hará mientras la variable i (que comienza siendo 3) sea menor o igual que la variable max (10 porque no me apetece sacar más de 10 números de Fibonacci).

Además el ejemplo sirve para ver como se hacen operaciones aritméticas en bash

n=$((${n_2} + ${n_1}))
i=((${i}+1))

Si no utilizasemos los dobles paréntesis bash no sabría que querriamos hacer una suma y lo que haría es concatenar los valores como si de una cadena de texto se tratase, n valdría 1+1 en la primera iteración (no 2) e i valdría 3+1 (no 4).

7 comentarios to “Aventurandose por los shell scripts”

  1. alhendin said

    Hola un saludo, estoy empezando en esto de GNU/Linux, soy usuario de Ubuntu, he leido tu post y no me he enterado de nada, pero ya habrá tiempo, poco a poco, y sin agobiarse.

    Escribo esto para darte las gracias por tu trabajo.

  2. Martin said

    saludos
    gracias por tu aporte…

  3. […] por zenon on Noviembre 29, 2007 Hace varios meses escribí una pequeña introducción sobre los shell-scripts utilizando bash como shell, y se me quedaron un montón de cosas en el tintero. Algunas de las […]

  4. yoli said

    no se si me podreis ayudar, pero espero que si.
    tengo que hacer 1 shell-script que muestre los procesos en el sistema que tengan 1 determinada prioridad, pasada como parametro. esto lo he conseguido, pero además si no se le pasase parametro deberia mostrar los de la prioridad minima,no lo consigo.si alguien tiene alguna idea, lo agradeceria.por cierto el comando que muestra las prioridades es ps -el y el campo prioridad es el NI.además la prioridad es más alta cuanto más bajo es este valor.gracias

  5. mlm said

    solo quisiera saber como convertir unas fotos con extension shell al formato jpg
    gracias

  6. zenon said

    como convertir unas fotos con extension shell al formato jpg

    ¿Fotos con extensión shell? ¿qué es eso?
    Un shell script no es más que un conjunto de comandos agrupados en un fichero y que se ejecutan en un terminal, y que yo sepa no se trata de una extensión de imágenes.

    Si lo que tienes son fotos en otros formatos distintos al jpg (por ejemplo png, bmp, gif, tiff, …) puedes utilizar el comando convert, que puedes encontrar en el paquete imagemagick (este paquete existe tanto en Ubuntu, como en Debian, aunque desconozco como se llamará en otras distribuciones de GNU/Linux).

  7. Mycro said

    Thanks for share this info brother…Very usefull!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: