Sie sind auf Seite 1von 37

CAPITULO III

PROGRAMACION BSICA
DE SHELL

Objetivos:

Aprender a programar script shell.


Conocer el funcionamiento del shell: ejecucin de un comando, caracteres
especiales del shell usados habitualmente (redirecciones, tuberas,),
configuracin del entorno de trabajo del usuario (variables y archivos de
entorno,).
Aprender las base de la programacin (variables, estructuras de control,
estructuras de repeticin y funciones) mediante una gran cantidad de
ejemplos.
Conocer las utilidades anexas indispensables para el tratamiento de cadenas de
caracteres y de archivos de texto con Shell script.

Elaborado por:
Prof. Giovana Garrido

31
3.1 Introduccin
Al entrar en un Linux en modo consola estamos usando un shell o interprete de comandos. Un
shell no es ms que un programa que le facilita al usuario interactuar con el sistema operativo:
administrar el sistema, programar, crear todo tipo de contenidos de texto, etc..., para hacer todo
eso el usuario debe utilizar una serie de comandos que le permiten manipular ficheros,
procesos, etc... Tambin se define shell como el programa-interface, que se provee como un
elemento comunicacional entre el usuario y el S.O.

El shell presenta dos grandes funciones, que son:


Servir de intrprete de comandos: Acepta los comandos escritos y se encarga de su
ejecucin. A la hora de interpretar comandos, puede pasar que se trate de comandos
internos del propio SO de tal forma que el mismo (shell) se encarga de su propia
ejecucin, o que se trate de rdenes o comandos realizados por los usuarios (scripts,
etc..) en tal caso da paso al KERNEL y es este quien ejecuta y procesa estas rdenes.
Servir como intrprete de programacin: Presentando las mismas caractersticas de
un lenguaje de programacin interpretado de alto nivel. Como ya dije el equivalente a
MSDOS. Pero muchos ms potentes.

En los sistemas Windows el shell es un entorno visual intuitivo y fcil de utilizar, aunque
tambin tiene otro shell disponible, una herencia del sistema MS-DOS que no ha evolucionado
mucho. En Linux disponemos de multitud de entornos visuales para elegir, pero la gran
diferencia respecto a Windows es que en Linux el entorno grfico no es ms que un programa
ms; es algo opcional que podemos lanzar desde un shell o intrprete de comandos. La otra
diferencia importante es que el shell de linux es una herramienta muy poderosa.
Existen distintos intrpretes de comandos en el mundo Unix: csh, bash, tsh, ksh,.., pero salvo
pequeas diferencias todos son parecidos. En este documento partimos sobretodo de bash2,
ya que est muy extendido a travs de Linux.

Archivos de configuracin del Shell:


/etc/profile - Archivo de configuracin para todos los shells compatibles con Bourne Shell
(aplica para todos los usuarios).
/etc/bash.bashrc - Archivo de configuracin para bash (aplica para todos los usuarios).
/.profile, /.bash profile, /.bashrc - Archivos de configuracin para el usuario. Se recomienda
agregar todas las configuraciones en /.bashrc.

Que es un script?
Es un tipo de "nueva" programacin (interpretada) o estilo de lenguajes que se impone da a
da en el mundo de la informtica, debido principalmente a su facilidad, funcionabilidad.
Generalmente los scripts son programados con lenguajes de relativa facilidad pero no por ello
son menos funcionales que cualquier otro programa realizado en un lenguaje de alto nivel (C,
pascal, delphi, Vbasic, etc.).
Los scripts (guiones) son meros ficheros de texto ASCII que presentan una serie de rdenes y
estructuras organizadas secuencialmente. As pues el script se ejecuta de forma lineal-
secuencial orden tras orden.
Los lenguajes scripts son lenguajes "interpretados". Lo que quiere decir que sus rdenes
secuenciales son interpretadas por un sistema o programa padre.
Hoy en da es muy habitual haber odo hablar de este tipo de programacin, dando lugar a una
serie de lenguajes-scripts, cada uno con su propia sintaxis y ordenes especiales, pero todos
ellos presentan algo en comn y es que no dejan de ser guiones.

Algunos lenguajes -scripts son:


Para el desarrollo de webs
JavaScripT: Lenguaje-script que permite la creacin de pginas webs dinmicas
locales (en el propio navegador).
PHP,ASP, etc...:Lenguajes-scripts que permiten la creacin de pginas webs dinmicas
en servidor.
Para los clientes de IRC:

32
mIRC: Presenta su propio lenguaje script (revolucionario donde los haya).
Podemos aumentar con el, la potencia de nuestro mIRC, claro ejemplo de script sera
el OrioN ScripT para mIRC
(www.ircorion.cjb.net).

3.2 Para qu sirven los script shell


Unix es capaz de ejecutar dos tipos de ficheros (siempre que tengan permiso de ejecucin):
ficheros binarios, resultado de compilar un programa escrito en un lenguaje de programacin
scripts, el cual definimos en el siguiente prrafo.

Un script de shell no es ms que un fichero de texto que contiene una serie de comandos o
sentencias de un lenguaje de scripting (interpretado) del sistema Linux, adems de los
comandos que forman parte del Shell (built-in) con los que podemos crear estructuras que
facilitan la programacin de scripts complejos.

Un script siempre debe tener en su primera linea lo siguiente:


#!/path/al/interprete
en donde /path/al/interprete puede ser una referencia a cualquier intrprete instalado: Perl,
PHP, Python, Ruby. . .
La shell ejecuta el intrprete y le pasa como parmetro el propio script.
Cualquier shell tiene un lenguaje de scripting y por tanto puede interpretar scripts escritos para
ella
As un script de shell escrito para bash empezar por:
#!/bin/bash

3.3 Historia de los shell

La primera Shell fue programada por Steven Bourne (llamada por este motivo Bourne-Shell).
Segn las versiones se le llama sho bsh. Es una shell muy limitada, y usa una sintaxis de
comandos usada en los primeros sistemas UNIX.

Cronolgicamente, la siguiente shell fue la c-shell o csh, desarrollada por el unix BSD de
Berkeley. Y cmo su nombre indica, usa comandos muy parecidos al lenguaje de programacin
C. Tambin existe una shell llamada tcsh, que es una especie de c-shell mejorada, siendo
capaz de chequear ficheros, completar nombres de variables, aliases. No suele venir incluida
en las instalaciones estndar.

En 1986, David Korn en los laboratorios AT&T program la korn- shell (ksh) que naci de juntar
lo mejor de la bourne shell y la c-shell.

En la mayora de los sistemas Linux, viene por defecto la shell bash (Bourne-Again-shell, en
referencia al inventor de la primera Shell). Esta Shell posee toda la funcionalidad del sh con
caractersticas avanzadas de C Shell, por eso cualquier script escrito para una shell sh correr
perfectamente. La shell bash fue programada por desarrolladores del proyecto GNU. La ventaja
principal es su potencia y que es gratuita. Por este motivo nosotros usaremos esta Shell .

Actualmente existen varios tipos de Shell, sin embargo, la Bouner Shell fue la primera usada
para propsitos generales.
Al principio, era muy limitada, as que solo se usaba como una herramienta para correr otras
herramientas. Existan las variables, ciclos, y sentencias Unix y sus derivados, incluyen la
Bouner Shell. Y la mayora de las Shell actuales, son derivadas de esta.

Tipos de Shell:

33
Al igual que las distribuciones de Linux, existen varios tipos de Shells, cada una orienta a
satisfacer diferentes necesidades que los diferentes tipos de usuarios pudieran tener. Por
mencionar algunas:
1. Z (zsh)
2. Korn Shell (ksh)
3. Bouner Again Shell (Bash)
4. TCSH (C Shell o csh)

La Shell es
Un programa que acta como interfaz entre el usuario y el sistema operativo.
Un software que atiende las ordenes tecleadas por el usuario y las traduce a instrucciones en la
sintaxis interna del sistema.
Es afortunadamente algo ms que un intrprete de comandos. Entre sus funciones destacan:
1. Interpretar, ejecutar rdenes y comandos.
2. Configurar el entorno.
3. Asignar valores a variables.
4. Sustituir variables por su valor.
5. Re direccionar entradas y salidas.
6. Generar nombres de archivos.
7. Encauzar listas de rdenes o tuberas.
8. Es un completo lenguaje intrprete de programacin.

3.4. Conceptos bsicos

3.4.1 Variables

Uno de los usos ms corrientes de las variables del shell consiste en describir valores que
deben ser usados en el entorno de ejecucin de ciertas rdenes. Al abrir una sesin del shell,
el usuario dispone de un entorno con una serie de variables ya definidas. Entre ellas, algunas
de las ms importantes son PATH, BASH, HISTSIZE, HISTFILESIZE, HISTFILE, HOME,
HOSTNAME, LANG, USER, UID.

34
La shell bash les permite a los usuarios establecer y hacer referencia a las variables de shell.
Una variable de shell es simplemente un valor con nombre que la shell recuerda. Las variables
de shell se pueden utilizar en comandos y scripts de shell y pueden tambin referenciarse en
programas como opciones de configuracin. Por ejemplo, el cliente de correo electrnico mutt
ejecuta un editor externo al escribir un mensaje. Por defecto este editor es vi. Sin embargo,
antes de ejecutar vi comprobar si una variable llamada EDITOR se ha establecido. Si se ha
establecido, entonces el comando definido por EDITOR se utiliza en lugar de vi. La mayora de
los programas que lanzan editores externos funcionan del mismo modo.
Hay dos tipos de variables de shell: variables locales y variables de entorno. Una variable local
existe solo dentro de la shell en la cual se crea. Las shells hijas heredan las variables de
entorno como cuando se lanza una terminal despus de iniciar sesin.
Primero, veremos cmo definir una variable local, luego hablaremos acerca de cmo definir
variables de entorno incluyendo la bash misma.

El configurar las variables locales es bastante sencillo. En el siguiente ejemplo, practica


establecer la variable A con el valor apple.
[practica@ubuntu]$ A=apple
Si usted sigue, asegrese de no dejar ningn espacio a los lados del signo =. Ahora la shell se
"cuelga"a esta asociacin por todo el tiempo que exista la shell (o hasta que se anule
explcitamente, ver a continuacin). Cada vez que prince quiera usar el valor "apple", puede
usar la variable A en su lugar, iniciando la variable con el signo ($), como en el comando echo
mostrado abajo. Esto se llamadesreferenciar la variable A.
[practica@ubuntu]$ echo $A
apple
La variable se puede utilizar en cualquier parte de la lnea de comandos (o en los scripts de
shell). Qu sucede si prince, en lenguaje colorido, decidiera escribir unas cuantas lneas
acerca de las manzanas (o apples en ingls) y las almacenara en un archivo llamado
ode_to_apple.txt. La siguiente lnea podra ayudarlo a empezar:
[practica@ubuntu]$ echo "Oh, Yo deseo un helado" >> ode_to_$A.txt
[practica@ubuntu]$ ls
ode_to_apple.txt

En el shell se pueden definir variables y por tanto dentro de los scripts tambin. Aqu no hay
declaracin de tipos pero s que podemos definir variables que contienen nmeros, cadenas,
booleanos e incluso arrays.
Para declarar una variable basta con hacer:
VARIABLE=valor
As como lo aplicado en el ejemplo anterior A=Apple, y se referencian con una sintaxis
$VAR, tal como $A

Qu puede utilizarse como nombres de variables? Los nombres de variables pueden ser
cualquier cadena de caracteres alfanumricos (A-Z, a-z, 0-9), y el guin bajo (_), pero no
pueden comenzar por un nmero. Las variables de shell distinguen maysculas de minsculas,
como se muestra a continuacin.
[practica@ubuntu]$ B=banana
[practica@ubuntu]$ echo $B es mi fruta favorita
banana es mi fruta favorita
[practica@ubuntu]$ echo $b es mi fruta favorita
es mi fruta favorita

En el primera impresin en pantalla, $B fue remplazado por el valor banana. Cmo fue
referenciado $b? Si se le pide a la shell referenciar una variable no establecida, sta remplaza
la referencia de la variable con una cadena vaca (en otras palabras, con nada). Dado que b se
considera como una variable diferente a B, y que la variable b nunca ha sido asignada, la shell
remplaza la referencia $b con nada. Por protocolo, las variables suelen definirse con
maysculas, pero esto no es ms que protocolo.
Cul puede ser el valor de la variable? Cualquier cosa. El truco se presenta en la asignacin.
Cuando se asignan las variables, la sintaxis es nombre=valor, sin dejar espacios. Qu
sucedera si practica quisiera que la variable FRUIT apuntara a la frase mushy bananas?
[practica@ubuntu]$ FRUIT=mushy bananas

35
-bash: bananas: command not found

Nos hemos tropezado con una sintaxis avanzada para configurar las variables, es decir
nombre=valor comando, el cual establece la variable name slo para la ejecucin del
comando especificado. La Shell bash obedientemente estableci la variable FRUIT en el valor
mushy y fue a ejecutar el comando bananas, con resultados esperables. Pero esto no es lo
importante, lo importante es que si quiere establecer una variable a un valor que contenga
espacios, debe incluir el valor entre comillas.
[practica@ubuntu]$ FRUIT="mushy bananas"
[practica@ubuntu]$ echo $FRUIT es mi fruta favorita
mushy bananas es mi fruta favorita

Con esta modificacin, practica obtiene la conducta correcta desde la shell bash, si no la
gramtica inglesa correcta.

La podemos exportar para que se convierta en una variable global.


export VARIABLE

A partir de que se crea la variable ya podemos acceder a ella a travs de su nombre con el
smbolo del dlar por delante.
echo $VARIABLE

Este es un ejemplo de uso de variables:


#!/bin/sh
# Muestra el uso de variables
# No existen los tipos
# definicin de variables
una_variable=666
MI_NOMBRE="Richard"
NOMBRES="Iigo Asier Sten Roberto Pello"
BOOLEANO=true
echo "Echemos un ojo a las variables "
echo "Un nmero: ${una_variable}"
echo "Un nombre ${MI_NOMBRE}"
echo "Un grupo de nombres: ${NOMBRES}"
# Al script se le pueden pasar argumentos. Para recogerlos
# hay que usar : ${nmero} donde:
# ${0} : nombre del script
# ${1} : primer argumento
# ${2} : segundo argumento
# ...etc.
echo "Has invocado el script pasndome ${0} eta ${1} "
# Otras variables especiales
# $# : Nmero de argumentos
echo "Me has pasado $# argumentos"
# $@ : grupo de parmetros del script
echo IDa: ${!} y $@
# Variables de entorno
echo "Mi directorio actual: ${PWD} y mi usuario ${UID}"

Al terminar con una variable, la variable se puede desligar de su valor con el comando unset.
[practica@ubuntu]$ unset A
[practica@ubuntu]$ echo $A
[practica@ubuntu]$

Metacaracteres de la Shell
Existen ciertos caracteres que tienen un significado propio para la shell. Estos caracteres son:
* ? [ ] [!] |
> 2> >> 2>> >&

36
< <<
() & $ && ||

3.4.2 Variables de entorno

El configurar y resolver variables debera ser bastante sencillo, (siempre y cuando se acuerde
de los espacios). Ahora presentaremos un concepto un poco ms sutil y mucho ms til:
variables de entorno.

As como la shell bash permite asignar parejas de valores-nombre llamados variables de shell,
el kernel de Linux permite a cualquier proceso definir las parejas nombre-valor llamadas
variables de entorno. Estas variables son una parte del proceso almacenado en el kernel,
simplemente como el id del proceso, el id del usuario y el directorio actual de trabajo son parte
del proceso. Lo ms importante es que cada vez que se inicie un proceso (tal como la shell
bash iniciando el comando ls), las variables de entorno son heredadas por el proceso hijo. Esto
le permite a los usuarios utilizar la shell bash para crear o modificar una variable de entorno y
luego todos los comandos iniciados por la shell heredarn esa variable.
Cmo creamos variables de entorno dentro de la shell bash? Primero, una variable de shell
se crea y luego la variable de shell es "promovida" a una variable de entorno mediante el
comando export, (la variable ser luego exportada a cualquier proceso hijo futuro), el cual a
continuacin presentamos el formato. Considere el siguiente ejemplo:
[practica@ubuntu]$ A=apple

Comando export
Exportar variables del ambiente, o muestra todas las variables que se exportan a otros
ambientes.
sintaxis: export variable[=value]
export [ opc ione s ] [<nombre>[=<valor >] ]
sintaxis: export
Por ejemplo, si queremos que el valor de la variable EDITOR pase a las subshell que
sean hijas de la shell activa, tendremos que poner
$ export EDITOR
En la shell bash, podemos realizar en una sola operacin la asignacin de un valor y
exportarla, por ejemplo
$ export EDITOR=vi
No todas las shell permiten esta operacin
Ejemplo:

Asignar la palabra contenido a una variable llamada AA


$ AA=contenido
Mostrar el contenido de la variable en pantalla.
$ echo $AA
Abrir una shell hija de la anterior.
$ /bin/bash
Mostrar de nuevo el contenido de la variable
$ echo $AA
Salir de la subshell activa
$ exit
Mostrar de nuevo el contenido de la variable
$ echo $AA
Exportar la variable
$ export AA
Abrir una shell hija de la anterior.

37
$ /bin/bash
Mostrar de nuevo el contenido de la variable
$ echo $AA

[practica@ubuntu]$A=apple
[practica@ubuntu]$B=banana
[practica@ubuntu]$echo a:$A b:$B
a:apple b:banana
[practica@ubuntu]$export A
[practica@ubuntu]$bash
[practica@ubuntu]$ps
PID TTY TIME CMD
2251 pts/5 00:00:00 bash
2316 pts/5 00:00:00 bash
2342 pts/5 00:00:00 ps
[practica@ubuntu]$echo a:$A b:$B
a:apple b:
[practica@ubuntu]$exit
exit
[practica@ubuntu]$echo a:$A b:$B
a:apple b:banana
[practica@ubuntu]$unset A B

El usuario prince ha creado dos variables de shell, A y B.


La variable A se promueve a una variable de entorno con el comando export.
El usuario prince inicia una subshell bash.
Al ejecutar el comando ps, prince confirma que hay otras shells ejecutndose: el padre y el
hijo (su shell actual).
Dado que la variable A pasa a ser una variable de entorno, sta fue heredada por la shell
hija del padre. Por el contrario, la shell hija no sabe nada de la variable de shell padreB.
Cuando prince sale de la shell hija, vuelve a la shell padre, donde la variable B est an
definida.
Por ltimo, prince desenlaza tanto la variable de entornoA como la shell de entorno B con
el mismo comando unset, el cual se explica ms adelante.

Las variables de entorno suelen utilizarse para configurar comandos con informacin acerca de
configuraciones locales o en otras palabras, la informacin acerca del entorno local. A manera
de ejemplo, muchos comandos buscarn una variable de entorno llamada LANG para
determinar el lenguaje del usuario y modificar su salida como corresponde.
$ echo $LANG
en_US.UTF-8
$ date
Fri Aug 1 11:54:24 EDT 2002
$ LANG=de_DE
$ date
Fre Aug 1 11:54:53 EDT 2002
$ LANG=es_ES
$ date
vie ago 1 11:55:09 EDT 2002

Al establecer la variable de entorno LANG para de_DE, la abreviatura habitual para el da


"viernes" en alemn entonces se convierte en la abreviacin alemana por regla. Al establecer
LANG como es_ES, los efectos son incluso ms obvios, puesto que las abreviaturas de los das
y meses han cambiado al espaol (como tambin las convenciones de las maysculas).

Comando env

38
Cuando el shell genera un proceso hijo para ejecutar una orden, por defecto le pasa como
variables de entorno todas las que l tenga definidas.
No obstante, si se quieren fijar explcitamente las variables de entorno que una orden debe
usar, se puede usar la orden env para ejecutar la orden del shell deseada.
El comando env lista todas las variables del ambiente o sea, lista slo variables que han sido
exportadas al entorno.
El formato de la orden env es
env [ opcin ] . . . [<nombre>=<valor >] . . . [<Comando> [<argumento > ] . . . ]

Ejemplo:
$env
PWD=/home/usuario/public_html/docs/shell
LTDL_LIBRARY_PATH=/home/usuario/.kde/lib:/usr/lib
HOSTNAME=www.bdat.com
LD_LIBRARY_PATH=/home/usuario/.kde/lib:/usr/lib
QTDIR=/usr/lib/qt-2.2.2
CLASSPATH=./:/usr/lib/jdk118/lib/classes.zip
LESSOPEN=|/usr/bin/lesspipe.sh %s
PS1=[u@hW]$
KDEDIR=/usr
BROWSER=/usr/bin/netscape
USER=usuario
MACHTYPE=i386-redhat-linux-gnu
LC_ALL=es_ES
MAIL=/var/spool/mail/usuario
EDITOR=joe
LANG=es
COLORTERM=
DISPLAY=:0
LOGNAME=usuario
SHLVL=4
LC_CTYPE=iso-8859-1
SESSION_MANAGER=local/www.bdat.com:/tmp/.ICE-unix/965
SHELL=/bin/bash
HOSTTYPE=i386
OSTYPE=linux-gnu
HISTSIZE=100
HOME=/home/usuario
TERM=xterm
PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/lib/jdk118/bin:./:/sbin:/usr/sbin:/usr/local/sbin:/opt/nets
cape
GROFF_TYPESETTER=latin1
LESSCHARSET=latin1

En el nivel de kernel, cada proceso tiene una coleccin de variables de entorno que los
procesos hijos heredan.
El comando export convierte una variable de shell en una variable de entorno.
Los comandos set y env listan las variables de shell y las variables de entorno,
respectivamente.

Listado de variables:

Variable $PATH
Ejecucin de los comandos.
Al ingresar un comando, el shell busca el programa a ejecutar en la lista de caminos
que contiene la variable PATH.
Esta variable contiene una lista de caminos separados por : (dos puntos).
Si se encuentra en el PATH se ingresan directamente. Si no se encuentra en el PATH
se ubica en el directorio del comando y se digita:

39
./command
Ejemplo
> PATH=/usr/bin:/usr/openwin/bin:.
> export PATH
> PATH=$PATH:/usr/ucb
> echo $PATH
/usr/bin:/usr/openwin/bin:.:/usr/ucb

Variable $PS1
Prompt del usuario. Especifica el indicador del sistema. Lo habitual es que PS1 sea "$" para
usuarios normales y "#" para root.

Variable $PS2
Especifica el indicador secundario del sistema. Aparece cuando no se ha completado una
orden.
Variable $LANG
Especifica el lenguaje que se aplica al usuario. Para espaol se utiliza "es".

Variable $TERM
Contiene el tipo de terminal. TERM
Indica el tipo de terminal que se est utilizando. Por ejemplo, si estamos en la consola el valor
de TERM ser "linux", para usar las caractersticas del teclado. Si entramos por telnet desde
w9x entonces probablemente tengamos que poner vt100.

La base de datos de configuracin de terminal se encuentra en:


/etc/termcap RedHat SuSE
/etc/terminfo/* Debian

Variable $HOME
Contiene el directorio personal del usuario

Variable $HOSTNAME
Contiene el nombre del host.

Variable $CDPATH
Esta variable por defecto est vaca. Contiene directorios que se utilizarn con el
comando cd. Al hacer cd se busca en los path definidos en la variable.
Ejemplo:
CDPATH=~/dir:/tmp
cd /etc
cd subdirectorio
pwd
/root/dir/subdirectorio

Comando set
Permite la modificacin de variables del shell del usuario, y tambin lista todas las variables
locales y variables del ambiente.
sintaxis: set [ opc i one s ] [-o <nombre-opcin >] [<argumento >. . . ]
Ejemplos
set #lista todas las variables
set -o #lista cada opcin del shell y su propiedad (on|off)
set -o allexport #se activa esta opcin cada variable que
se defina automticamente ser exportada.
set +o allexport #se desactiva la opcin.

40
Opciones activas:
SHELLOPTS=allexport:braceexpand:emacs:hashall:histexpand:hi
story:interactive-comments:monitor

[practica@ubuntu]$ set
BASH=/bin/bash
BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release"
[5]="i386-redhatlinux-
gnu")
BASH_VERSION='2.05b.0(1)-release'
COLORS=/etc/DIR_COLORS.xterm
COLUMNS=80
...
[practica@ubuntu]$ env
HOSTNAME=localhost
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
USER=prince
MAIL=/var/spool/mail/prince

Comando unset
Desasignar variables asignadas
sintaxis: unset variable

Comando declare
Agrega la variable a la lista de variables a exportar, otra forma de exportar.
Sintaxis declare [airx] variable

Ejemplo igual que export


declare -x variable[=value]

Comando readonly
Lista todas read-only variables, o asigna el atributo a una variable, estas variables no se
pueden cambiar o unset.
sintaxis: readonly
sintaxis: readonly variable

Para empezar podemos dar un vistazo a las variables de entorno del sistema:
linux~$ set
BASH=/bin/bash
BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release"
[5]="i386pclinuxgnu")
BASH_VERSION='2.05b.0(1)release'
COLUMNS=80
DIRSTACK=()
EUID=1000
GROUPS=()
HISTFILE=/home/usuario/.bash_history
HISTFILESIZE=500
...

41
DISPLAY Especifica qu clientes del servidor X deberan usar el entorno grfico.
Especifica qu equipo muestra la salida que se efecta en modo grfico. Ese equipo deber
tener un servidor grfico.

Variables especiales:

$0: Nombre del Shell-Script que se est ejecutando.


$n: Parmetro o argumento pasado al Shell-Script en la posicin n, n=1,2,...
$#: Nmero de argumentos.
$*: Lista de todos los argumentos.
$$: PID del proceso que se est ejecutando.
$!: PID del ltimo proceso ejecutado.
$?: Salida del ltimo proceso ejecutado.

Utilizacin de variables
Ejemplos
var=$(date +%a-%b)
echo $var
ls >file$( date +%a-%b).txt
var=$(ls b*)
cp $var /directorio

TABLA 2 OTRAS VARIABLES


Variable Definicin
PPID Nmero de identificacin del proceso padre de la interfaz de comandos.
OLDPWD Anterior directorio de trabajo, establecido por el comando "cd".
REPLY Cuando se usa el comando read de bash sin argumentos, esta variable recoge el contenido de la lnea
leda.
UID Numero identificativo (ID) del usuario, establecida en el arranque del shell.
EUID ID eficaz de usuario, inicializada en el arranque del shell.
BASH Nombre completo, incluida la ruta, del archivo que se ejecut para lanzar el shell.
BASH_VERSIN Numero de versin de Bash.
SHLVL Nivel del shell. Incrementa su valor en una unidad cada vez que se lanza una nueva interfaz de
comandos.
RANDOM Cada vez que se invoca a esta variable se obtiene un nmero entero aleatorio. La secuencia de
nmeros aleatorios proporcionadas por RAMDOM se puede inicializar simplemente asignndole un
nuevo valor a esta variable.
SECONDS Mantiene el nmero de segundos que han transcurrido desde que se ejecut el shell. Si asignamos un
valor a esta variable, la cuenta indicara los segundos transcurridos desde dicha asignacin, ms el valor
asignado.
LINENO Cuando se hace referencia a esta variable desde un script, indica la lnea dentro del script en la que se
le est haciendo referencia, considerando que la primera lnea se numera como 1. Si se invoca desde la
propia interfaz de comandos, el valor que devuelve es l nmero de lnea que hace la orden ejecutada
desde que se inici la interfaz de comandos.
HISTCMD Contiene la posicin dentro del archivo de historia de comandos que ocupa el comando actual.
HOSTTYPE Se trata de una cadena de texto describiendo el tipo de maquina en la que est ejecutando el bash.
HOSTNAME Nombre de la mquina.
OSTYPE Se trata de una cadena de texto describiendo el sistema operativo en el que s est ejecutando el
bash.
CDPATH Se trata de la ruta de bsqueda para el cd. Tiene una estructura similar a la variable PATH. Lo que
indica es donde se deben buscar los directorios especificados como argumentos al comando. Como
ejemplo habitual, podra contener <<:~:/usr>>.
ENV Contiene el nombre del fichero que define el entorno del shell en el que se ejecutan scripts. Algo as
como el archivo .bashrc para el shell cuando se inicializa, para lo relativa al entorno en que ejecuta un
script.
MAIL Cuando contiene el nombre de un archivo, bash comprueba en l la llegada de correo nuevo y avisa en
caso que se produzca.
MAILCHECK Determina el intervalo de tiempo en segundos que bash tomara para revisar si hay correos nuevos.
MAILPATH Al igual que PATH y CDPATH, esta variable contiene una lista, en este caso, de archivos que debern
ser comprobados para la posible llegada de correo. Se puede indicar u mensaje especfico para la
llegada de correo en diferentes buzones usando el carcter '?' como separador entre el archivo y el
mensaje. En ese caso, la variable $_ obtendr el nombre del buzn. Un ejemplo:

42
MAILPATH='/var/spool/mail/nlucas?"Tienes correo":~/mail/buzon?"Ha llegado algo al $_"'
PS3 Valor del tercer prompt. Este prompt es usado solamente por el comando select.
PS4 Valor del cuarto prompt y ltimo. Tan solo se usa cuando se est realizando un seguimiento de los
comandos mostrndose para indicar los pasos por los que se va ejecutando el comando. Para entrar en
el modo de seguimiento, basta con ejecutar set -x. Entonces veremos cmo cada comando que
ejecutemos se expande, mostrando las sustituciones que se hacen con los alias, las variables, etc.
HISTSIZE Contiene l nmero de comandos a guardar en el historial de comandos.
HISTFILE Contiene el nombre del archivo en el que se almacena el historial de comandos. Por defecto se trata
del fichero ~/.bash_history.
HISTFILESIZE Nmero mximo de lneas que puede contener el archivo de historia. Tengamos en cuenta que un
comando puede ocupar varias lneas.
PROMPT_COMMAND Si est definido, contiene el comando a ejecutar antes de presentar el prompt.
IGNOREEOF Indica cuantas veces ha de recibir el carcter EOF (End Of File, o la pulsacin de la tecla Crtl+D) antes
de salir de bash. Si el valor indicado no es numrico, se toma por defecto el 10. Si no est seleccionado,
una nica pulsacin basta.
TMOUT Si contiene un valor superior a cero, indica el nmero de segundos que se puede estar sin introducir un
comando al shell. Pasado este tiempo, la interfaz de comandos se cerrara.
FCEDIT Ruta y nombre del editor usado por defecto para el comando fc. Por defecto se usa vi.
FIGNORE Lista de subfijos de archivos que se ignoraran al intentar completar un nombre de archivo desde bash.
La lista estar formada por los subfijos ignorados, separados por un signo de dos puntos (:). Por
ejemplo <<.0:.tmp>>
INPUTRC El nombre del archivo de arranque. Por defecto es ~/.inputrc.
EDITOR En esta variable muchos programas buscaran la ruta y el nombre del editor a usar. Por defecto el
editor usado es el vi. Algunos de los programas que hacen uso de esta variable son crontab (con la
opcin -e), edquota y otros muchos.

3.4.3 Entrecomillado

En las operaciones con la shell distinguimos tres tipos de comillas con distintas
funcionalidades: las comillas dobles, las comillas simples y la comilla invertida, el acento grave
francs. A continuacin describimos las funciones:
' Engloban un literal. La shell no trata de interpretar nada de lo que haya comprendido
entre estas comillas.
" La shell expande las variables que haya especificadas sustituyendo su nombre por el
contenido. Para imprimir un $ es necesario protegerlo con una 1#1.
' La shell intenta ejecutar lo que haya comprendido entre estas comillas.

Hay tres clases de comillas, y su uso lo ilustran los siguientes ejemplos:


> echo mi home es $HOME
mi home es /home/usr1

>echo mi home es $HOME


mi home es $HOME

> echo el contenido de arch es `cat arch`


el contenido de arch es contenido de archecho

$HOME
>echo $HOME
/root
>echo '$HOME'
$HOME
>echo "'$HOME'"
'/root'

a. Simple

43
El contenido no es interpretado por el shell. Se suele usar para indicar caracteres literales. Por
ejemplo 'a' es tomada como un carcter literal no es procesada por el shell.
Las comillas `tilde` son el equivalente a $(comando) ejecutan el comando.

b. Doble

Agrupa una cadena de caracteres o string. Por ejemplo: "OrioN ScripT www.ircorion.cjb.net".
Se suelen usar para almacenar una string entera en una variable. Por ejemplo: VAR="hola soy
Quasi", aqui estaramos almacenando en la variable VAR el texto hola soy quasi.
Para ver el resultado basta con hacer: echo $VAR.
Las comillas dobles preservan el contenido de las variables.
Ejemplo:
Asignamos un valor a una variable:
$ AA="ls -la"
y observamos la diferencia entre:
echo '$AA'
echo "$AA"
y
echo $AA

Comillas invertidas: Hacen que se evalu el contenido y que su resultado sea devuelto como
el de una variable.
Por ejemplo. verfecha=`date`
Si ejecutamos esto, echo $verfecha, veramos como el valor devuelto por el comando date es
devuelto como una variable y almacenado en otra variable (verfecha).

Ejemplo de comillas invertidas:


$ A="ls /bin"
$ `echo $A`
Tambin podemos hacerlo de la siguiente forma:
$ A="ls /bin"
$ B=`$A`
$ echo $B

Personalizacin de la shell
Cada vez que se inicia una shell, se lee un fichero de configuracin. No es un fichero complejo,
es simplemente un fichero con rdenes que se ejecutan automticamente cada vez que se
inicia una nueva shell.

Diferentes shell utilizan diferentes ficheros de configuracin. Las shell C suelen llamar a este
fichero .login. Las shell de Bourne suelen llamar a este fichero .profile. En la shell bash,
adems del .profile, tenemos tambin el fichero .bashrc.

En este fichero vamos a ejecutar las rdenes y asignar valores a variables necesarios para
adaptar la shell a nuestras necesidades. En general, todo aquello que queramos que se ejecute
cada vez que entremos al sistema. Por ejemplo, nos puede interesar aadir a este fichero una
lnea como:
$ export LANG=es
para hacer que nuestro idioma predeterminado sea el espaol.

Tambin podemos poner (directorio efectivo) en la ruta de bsqueda de programas


ejecutables:

44
$ export PATH=$PATH:.
La shell bash tambin usa el fichero .inputrc para configurar el teclado

Cada vez que se inicia una shell, se lee un fichero de configuracin. No es un fichero complejo,
es simplemente un fichero con denes que se se ejecutan automticamente cada vez que se
inicia una nueva shell.

Diferentes shell utilizan diferentes ficheros de configuracin. Las shell C suelen llamar a este
fichero .login. Las shell de Bourne suelen llamar a este fichero .profile. En la shell bash,
adems del .profile, tenemos tambin el fichero .bashrc.

3.4.4 Ejecucin de shells

Con que crear un script?


Al ser un lenguaje interpretado, no necesitamos compilar su cdigo para poder ejecutarlo, con
lo que solo necesitamos escribir ASCII en un fichero. Para ello podemos usar cualquiera de
nuestros editores preferidos. En Linux es comn el uso del VI. A la hora de guardar el fichero,
bastara con salir del editor pulsando ":wq" para salir y guardar cambios. Sin embargo, puede
hacer uso de NANO si desea utilizar un editor distinto al VI.
Abriendo un fichero con VI: vi miScript o nano miScript
Con este comando crearamos y abriramos un fichero con el nombre de miScript. (Vase mas
informacin sobre el editor VI en tutorial Comandos bsicos Linux en el Internet).

Comenzando a crear un Shell script

En principio, consideraremos como script a cualquier fichero de texto que contenga una
secuencia de comandos de la shell que estemos usando, con una sintaxis correcta. En los
sistemas Unix/Linux se pueden usar estos scripts de muy diversas formas:

Arranque y parada del sistema: El directorio /etc/init.d contiene dichos scripts, que
son llamados en el inicio y parada del sistema operativo, o cuando se produce un
cambio de nivel de ejecucin (se arrancan o paran servicios del sistema). La finalidad
de estos scripts es principalmente la de arrancar procesos que acten como servicios,
como por ejemplo el demonio cron que programa tareas, o bien realizar
configuraciones iniciales, como establecer las direcciones TCP/IP de las tarjetas de
red.
Aunque la implementacin de estos scripts vara de un sistema operativo a otro, la
tcnica usada en todos los casos es similar. Suelen usar una estructura case para
analizar la variable $1 que es asignada al primer argumento con el que se le llama. En
funcin de que este argumento sea start o stop o cualquier otra opcin, se arrancarn
dichos servicios o se detendrn. Un ejemplo muy tpico es el script que arranca el
demonio cron para programacin de tareas (veremos ms adelante la aplicacin del
mismo). O sea, # /etc/init.d/crond start
Inicio de sesin de usuario: Cuando un usuario inicia una sesin con Bash, se
ejecutan los comandos de /etc/profile, y posteriormente busca uno de los ficheros
$HOME/.bash_profile, $HOME/.bash.login o $HOME/.profile en ese orden, y ejecuta los
comandos del primero que encuentre. Ntese que la variable HOME contiene el
directorio de trabajo del usuario.
En todos los casos, dichos scripts no tienen permisos de ejecucin ya que en realidad
son invocados por la propia shell de inicio de sesin y ledos sus comandos uno a uno.
Si no se hiciera as, sino de la forma tradicional, se generara un subproceso Shell que
sera el que se quedara con las definiciones de variables de entorno que es lo que se
suele definir en estos scripts de inicio. De esa forma, al acabar la ejecucin, se
perderan dichas definiciones.
Como comando: Podemos crearnos nuestra propia secuencia de comandos para
realizar una tarea que siempre se repite de la misma forma, y evitando as tener que
teclear todos los comandos manualmente. Adems estos scripts pueden programarse
para que se lancen a una determinada hora gracias a los demonios de programacin
de tareas (cron o anacron).

45
Como ejecutar un script?
Es costumbre que un script de shell sea un fichero con extensin .sh
Bastara con poner: sh namefile
sh: Era la orden encargada de ejecutar scritps. A continuacin el nombre del fichero que
contiene el guin. Sin embargo, veremos en los siguientes prrafos otra forma de ejecutarlos.

Otra forma de para poder ejecutar los ficheros deben ser ejecutables por tanto si no es
ejecutable hay que forzar que lo sea:
linux~$ chmod u+x scriptshell.sh
o con nmeros:
linux~$ chmod 755 scriptshell.sh

A partir de ah ya podemos ejecutar el script invocando directamente el fichero. En los sistemas


linux y en el shell bash2 debemos hacerlo especificando el directorio actual:
linux~$ ./scriptshell.sh

Si no ponemos ./ el script no se ejecutar y el sistema dir que no lo encuentra.


Otra forma de ejecutar el script es usar el comando source. A travs de este comando
podemos ejecutar un script aunque no tenga permisos de ejecucin.
linux~$ source scriptshell.sh
Si no ponemos ./ el script no se ejecutar y el sistema dir que no lo encuentra.

Hola mundo
Este es el aspecto que tendra el script ms bsico posible:
#!/bin/bash
# Esto es un comentario
echo "Hola mundo"

Este sera similar pero usando una variable:


#!/bin/bash
# En la primera linea establezco con qu shell se debe ejecutar
# Se define una variable
SALUDO="Hola mundo"
echo n
"Este script te dice: "
echo ${SALUDO}

subshell
Para la ejecucin de programas de shell, la shell se encarga de interpretar unas rdenes en
unos casos o de lanzar el programa adecuado en otros casos. En general, cuando lanzamos la
ejecucin de un conjunto de rdenes agrupadas en un programa de shell, se abre una nueva
shell (subshell hija de la anterior) que es la encargada de interpretar las rdenes del archivo.
Una vez concluida la ejecucin esta subshell muere y volvemos a la shell inicial. Esto es
importante tenerlo presente para saber el comportamiento de los programas. Por ejemplo, los
cambios hechos en las variables de shell dentro de un programa no se conservan una vez
concluida la ejecucin.

Vamos a ilustrar este comportamiento con nuestro primer ejemplo de programa de shell:

Creamos un programa en un archivo de texto, lo ejecutamos, comprobamos que se crea una


nueva shell y que los cambios en las variables hechos dentro del programa no se mantienen
una vez concluidos. Editamos un archivo llamado "pruebashell" con el siguiente contenido:
echo "******** GUIN ********"
echo "el valor previo de VAR es ** $VAR **"
VAR="valor asignado dentro del guin"
echo "Ahora VAR vale ** $VAR **"
ps
echo "******** FIN DEL GUIN ********"

46
Con este guion mostramos el valor previo de una variable llamada VAR, le asignamos un valor
nuevo y tambin los mostramos. Para verificar que se lanza una nueva shell mostramos la lista
de procesos con la orden ps.

Una vez editado el archivo tendremos que asignarle el permiso de ejecucin


$ chmod u+x pruebashell
despus asignamos un una valor a la variable VAR para comprobar cmo cambia. Adems
tendremos que exportarla par que la shell hija pueda heredarla:
$ export VAR="valor previo"
Ahora mostramos la lista de procesos para ver cuantas shell tenemos abiertas:
$ ps
o bien
$ ps | wc -l

y a continuacin ejecutamos el guin "pruebashell":


$ ./pruebashell
y volvemos a mostrar el contenido de la variable:
$ echo $VAR
Podremos observar como aparece una shell ms. Si la variable VAR est exportada veremos
como muestra el valor que asignamos antes de ejecutar el guion y como muestra el que le
asignamos dentro del guion. Y al final, al mostrar la variable VAR, observamos cmo nos
muestra el valor que tena antes de ejecutar el guion; el guion no ha modificado la variable.

Este mismo comportamiento se puede aplicar a la orden cd. Veamos el siguiente ejemplo, un
simple script que cambia de directorio.

Editamos el archivo llamado "cambia" con el siguiente contenido:

echo "cambiando de directorio"


cd /tmp
echo "estamos en:"
pwd

Es decir, el script simplemente cambia al directorio /tmp.

Una vez editado le asignamos el permiso de ejecucin


$ chmod u+x cambia
Ahora mostramos nuestro directorio activo
$ pwd
Ejecutamos el script
$ ./cambia
y volvemos a comprobar nuestro directorio activo
$ pwd
y observamos cmo estamos situados en el mismo directorio que antes de la ejecucin del
guion.

Por qu ocurre todo esto?, Porque todos los cambios se realizan en la subshell que ha
interpretado el guin

47
La orden read
La orden read permite asignar a una variable el contenido de una lnea de la entrada estndar.
As, si ponemos "read A", se leer de la entrada estndar informacin hasta que se detecte un
avance de lnea y se asignar a la variable A.
Ejemplo:
echo "Como te llamas?"
read nombre
echo "hola $nombre, como ests?"

Si hay ms variables en la orden read que palabras escritas, las variables que sobran por la
derecha se asignan a NULL. Si se introducen ms palabras que variables haya, todos los datos
que sobran por la derecha se asignan a la ltima variable de la lista.

3.4.5 Parmetros

Es posible pasar a un script, en la lnea de comando, los argumentos que necesita para su ejecucin.
Estos argumentos son llamados parmetros.
Existen dos categoras de estos: los parmetros posicinales y los parmetros especiales.

Los parmetros posicionales

En un programa de shell definen unas variables especiales, identificadas por nmeros, que
toman los valores de los argumentos que se indican en la lnea de rdenes al ejecutarlo. Tras el
nombre de un script se pueden aadir valores, cadenas de texto o nmeros separados por
espacios, es decir, parmetros posicionales del programa de shell, a los que se puede acceder
utilizando estas variables.

La variable $0 contiene el parmetro 0 que es el nombre del programa de shell.

Las variables $1, $2, $3, $4, ... hacen referencia a los argumentos primero, segundo, tercero,
cuarto, ... que se le hayan pasado al programa en el momento de la llamada de ejecucin.

Por ejemplo, si tenemos un programa de shell llamado parmetros con el siguiente contenido:
echo $0
echo $1
echo $2
echo $3
al ejecutarlo
$ parametros primero segundo tercero
prametros
primero
segundo
tercero

Estos son simplemente lo argumentos pasados al script, cuando un script es invocado.


Estos son almacenados en las variables reservadas 1,2,3,...9,10,11,... y pueden ser llamados
con las expresiones $1,$2...${10},${11}...

Nota: El shell Bourne est limitado a los parmetros del 0 al 9.

Ejemplo 1:
A continuacin un pequeo script que tan solo muestra ciertos argumentos pasados como
parmetros en funcin de su posicin

#!/bin/bash
# muestra_param.sh

48
echo "El 1er parmetro es: $1"
echo "El 3er parmetro es: $3"
echo "El 10mo parmetro es: ${10}"
echo "El 15 parmetro es: ${15}"

Tan solo hay que llamar al script y pasarle un cierto nmero de parmetros:

./muestra_param.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

El 1er parmetro es: 1


El 3er parmetro es: 3
El 10mo parmetro es: 10
El 15 parmetro es: 15

O tambin:

./muestra_param.sh uno 2 tres 4 5 6 7 8 9 diez 11 12 13 14 quince 16 17


El 1er parmetro es: uno
El 3er parmetro es: tres
El 10mo parmetro es: diez
El 15 parmetro es: quince

Si algunos parmetros contienen caracteres especiales o espacios, entonces es necesario


ponerlo entre comillas:

./muestra_param.sh uno 2 "el 3ro" 4 5 6 7 8 9 diez 11 12 13 14 "el 15" 16 17


El 1er parmetro es: uno
El 3er parmetro es: el 3ro
El 10mo parmetro es: diez
El 15 parmetro es: el 15

Modificacin de los parmetros posicionales

Durante la ejecucin de un programa de shell podra interesarnos modificar el valor de los


parmetros posicionales. Esto no lo podemos hacer directamente, las variables 1, 2, ... no
estn definidas como tales. Para realizar estos cambios tenemos que utilizar la orden set. Esta
orden asigna los valores de los parmetros posicionales a la shell activa de la misma forma que
se hace en la lnea de rdenes al ejecutara un programa; hay que tener en cuenta que no los
asigna individualmente, sino en conjunto.

Por ejemplo
$ set primero segundo tercero
$ echo $1
primero
$ echo $2
segundo
$ echo $3
tercero

Los parmetros especiales

Estas tambin son variables reservadas que permite en algunos casos efectuar operaciones
sobre los mismos parmetros.
Estos parmetros son los siguientes:

49
$0 Contiene el nombre del script tal como es invocado
$* El conjunto de todos los parmetros en un solo argumento
$@ El conjunto de argumentos, un argumento por parmetro
$# El nmero de parmetros pasados al script
$? El cdigo de retorno del ltimo comando
$$ El PID del shell que ejecuta el script
$! El PID del ltimo proceso ejecutado en segundo plano

3.5 Automatizacin de tareas con crontab (programacin de tareas)

La programacin de tareas regulares de mantenimiento, como la creacin de copias de seguridad,


se administra en Linux con el servicio cron, implementado por un daemon cron. Un daemon es un
servidor en ejecucin continua y que hace revisiones constantes, en espera de ciertas acciones que
habrn de emprenderse. Estas tareas se incluyen en el archivo crontab. El daemon cron revisa
constantemente el archivo crontab del usuario, para ver si es hora de emprender tales acciones.
Cualquier usuario puede configurar un archivo crontab por su cuenta. El usuario root puede
configurar un archivo crontab para emprender acciones administrativas relacionadas con el sistema,
como copias de seguridad de archivos a cierta hora, cada semana o mes.

La forma ms sencilla de programar tareas es usar la herramienta de escritorio cron. cron es un


recurso (herramienta) disponible en la mayora de los sistemas UNIX que permite programar
tareas (programas) para que se ejecuten en un momento determinado. Es muy til para
ejecutar utilidades de administracin del sistema de manera peridica, sin necesidad de
supervisin. Por ejemplo podemos apagar un equipo a una hora determinada o realizar
backups de manera automtica.

Cada usuario puede crear su propia configuracin de cron para ejecutar sus propias tareas,
limitado obviamente a los recursos sobre los cuales tiene permisos. Tambin existe un cron
para el sistema, en el cual es posible programar tareas que requieran privilegios de
administracin.

Entradas crontab
Una entrada crontab tiene seis campos: los primeros cinco se utilizan para especificar la hora
en que se realizar una accin, mientras el ltimo campo es la accin misma. El primer campo
especifica los minutos (0-59); el segundo especifica la hora (0-23); el tercero, el da del mes (1-
31); el cuarto, el mes del ao (1-12, o prefijos de mes como Jan y Sep); y el quinto, el da de la
semana (0-6, o prefijos como Wed y Fri), empieza con 0 como domingo. En cada campo de
hora, se especifica rango, conjunto de valores o usa el asterisco para indicar todos los valores.
Por ejemplo, 1-5 para el campo del da de la semana especifica de lunes a viernes. En el
campo de hora, 8, 12, 17 especificara 8 a.m., medio da y 5 p.m. Un * en el campo mes del ao
indica todos los meses. El formato del campo crontab es:
minuto hora da-del-mes mes da(s)-de-la-semana tarea

cron del usuario: m h dm mes ds comando Cron del sistema: m d dm mes de usuario comando
Donde:
minuto - (0 - 59)
hora - (0 - 23)
dia-del-mes - (1 - 31)
mes - (1 - 12)
da(s)-de-la-semana (0 - 7)
tarea actividad a realizar (comando)

Para agregar tareas al sistema cron, debe editarse un archivo de configuracin (crontab).
En el caso del cron del usuario, el archivo de configuracin se edita usando el comando
crontab -e. En el caso del cron del sistema, debe editarse el archivo /etc/crontab con cualquier
editor de texto.
$ crontab instala el fichero indicado como fichero crontab del usuario

50
$ crontab -e para editar este fichero de tareas que lee el servicio cron Al ejecutar este
comando se abre el editor nano.

$ crontab -l para mostrar un listado de las tareas actuales del usuario.


$ crontab -r elimina el fichero crontab del usuario ( es decir no usar este comando, ya que si se
usa habra que volver a crear el archivo crontab del usuario ).

Para crear una tarea usando cron es necesario editar el archivo /etc/crontab y agregar la tarea
tomando en cuenta los siguientes campos
1. Minuto
2. Hora
3. Da del mes
4. Mes del ao
5. Da de la semana
6. Comando a ejecutar
En el fichero crontab se define una lnea por tarea/trabajo a ejecutar y el formato de la misma
es el siguiente:

Algunos ejemplos (cron del usuario):

Ejecuta comando1 cada hora:


0 * * * * comando1

Ejecuta comando2 cada da a las 11:43 p.m.:


43 23 * * * comando2

Ejecuta comando3 todos los martes a las 12:00 m.d.:


0 12 * * 2 comando3

Ejecuta comando4 de lunes a viernes a las 12:00 a.m.:


0 0 * * 1-5 comando4

Para ejemplificar usaremos este pequeo script que genera un log de ejecucin
hola_crontab.sh
#!/bin/bash
date=$(date)
cat >> /var/log/task.log << EOF
hola soy una tarea programada y me ejecute $date y hoy es $(date
+%A)
EOF

Ejecutaremos el script de demo todos los das a 12:01 y a las 23:01


1 12,23 * * * bash hola_crontab.sh

51
Para impedir que un usuario utilice cron o mejor dicho el comando crontab, basta con agregar
su nombre de usuario al archivo /etc/cron.deny .Para permitirle su uso entonces sera agregar
su nombre de usuario en /etc/cron.allow, si por alguna razn se desea negar el uso de cron a
todos los usuarios, entonces se puede escribir la palabra ALL al inicio de /etc/cron.deny

*Ejemplos de uso:
Qu hace el siguiente comando?
01 04 1 1 1 /home/usuario/al_arrancar.sh
El comando anterior ejecutar /home/usuario/al_arrancar.sh a las 4:01am de Enero y cada
Lunes en Enero

Qu hace el siguiente comando?


01 04 * * * /home/usuario/al_arrancar.sh
El ejemplo anterior ejecutar /home/usuario/al_arrancar.sh a las 4:01am cada da de cada mes.
Qu hace el siguiente comando?
01,31 04,05 1-15 1,6 * /home/usuario/al_arrancar.sh
El ejemplo anterior ejecutar /home/usuario/al_arrancar.sh a las 4 o 5 y un minuto o 31 minutos
desde el 1 hasta el 15 de cada Enero hasta Junio.

Y si quiero ejecutar un comando cada 10 minutos?


*/10 * * * * /home/usuario/al_arrancar.sh

Sera esta lnea equivalente?


0,10,20,30,40,50 * * * * /usr/bin/somedirectory/somecommand
SI

Qu hace el siguiente comando?


45 04 * * * /home/usuario/al_arrancar.sh
Ejecuta el comando /home/usuario/al_arrancar.sh a las 4 y 45 de la maana

Qu hace el siguiente comando?


45 04 * * * /home/usuario/uno.sh && /home/usuario/dos.sh
Ejecuta el comando dos.sh a las 4 y 45 de la maana solo si uno.shse ejecuta con xito.

Variables de entorno para cron


El servicio cron tambin permite definir variables de entorno para utilizarlas con tareas
realizadas. Linux define variables para SHELL, PATH, HOME y MAILTO. SHELL designa la
shell que utilizarn las tareas, en este caso la shell BASH. PATH muestra los directorios en que
se encuentran programas y secuencias de comandos. En este ejemplo se muestran los
directorios estndar, /usr/bin y /bin, adems de los directorios del sistema reservados para
aplicaciones del sistema, /usr/sbin y /sbin. MAILTO designa a quin se enviar el correo con
el resultado de la tarea. Como opcin predeterminada, se enva el correo al usuario que lo
programa, pero tambin puede hacer que se enve a un usuario especfico (por ejemplo, la
direccin de correo electrnico del administrador o una cuenta de otro sistema en una red).
HOME es el directorio de inicio para una tarea, en este caso el directorio ms alto.
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

52
El directorio cron.d
En un sistema usado en exceso, el archivo /etc/crontab se llenar fcilmente. Tambin pueden
existir instancias donde ciertas entradas requieren diferentes variables. Por ejemplo, tal vez
necesite ejecutar tareas bajo una shell diferente. Para ayudar a organizar mejor sus tareas de
crontabs, se colocan las entradas crontab en archivos en el directorio cron.d. Todos los
archivos de este directorio contienen entradas crontab, del mismo formato que /etc/crontab.
Se les puede dar cualquier nombre. Se tratan como archivos adicionales de crontab, que cron
revisa para ver qu tareas se deben ejecutar. Por ejemplo, Linux instala el archivo sysstat en
cron.d conteniendo entradas de crontab para ejecutar herramientas permitiendo recopilar
estadsticas del sistema.

El comando crontab
Se utiliza el comando crontab para instalar sus entradas en un archivo crontab. Para esto,
primero debe crear un archivo de texto y escribir sus entrada de crontab. Guarde este archivo
con cualquier nombre que quiera, como miarchivocron. Despus, para instalar estas entradas,
inserte crontab y el nombre del archivo de texto. El comando crontab toma su contenido del
archivo de texto y crea un archivo crontab en el directorio /var/spool/cron, agregando el
nombre del usuario que emple el comando. En el siguiente ejemplo, el usuario root instala el
contenido de miarchivocron como el archivo crontab del usuario root. Esto crea un archivo
llamado /var/spool/cron/juan. Se controla el uso del comando crontab a usuarios regulares
con el archivo /etc/cron.allow. Slo los usuarios con sus nombres incluidos pueden crear
archivos crontab propios. En sentido opuesto, el archivo /etc/ cron.deny incluye usuarios a los
que se niega el uso de la herramienta cron, lo que evita programen tareas. Si no existe uno de
los archivos, el acceso se niega a todos los usuarios. Si un usuario no est en un archivo
/etc/cron.allow, se niega el acceso. Sin embargo, si el archivo /etc/ cron.allow no existe, y s
existe el archivo /etc/cron.deny, entonces todos los usuarios que no estn en /etc/cron.deny
se les permite el acceso automticamente.
# crontab miarchivocron

Edicin en cron
Nunca intente editar su archivo crontab directamente. En cambio, utilice el comando crontab
con la opcin -e. Esto abre el archivo crontab en el directorio /var/spool/cron, con un editor de
texto estndar, como Vi (crontab utiliza el editor predeterminado, como especifica la variable
de entorno de shell EDITOR). Para usar un editor diferente para crontab, cambie el editor
predeterminado al incluir el nombre del programa del editor en la variable EDITOR y exportar
esa variable.
Generalmente, la variable EDITOR se configura en la secuencia de comandos /etc/profile. Al
ejecutar crontab con la opcin -l, despliega el contenido de su archivo crontab y la opcin -r
elimina todo archivo. Al invocar crontab con otro archivo de texto de entradas de crontab se
sobreescribe el archivo crontab actual, reemplazndolo con el contenido del archivo de texto.

Organizacin de tareas programadas


Tiene la opcin de organizar tareas administrativas de cron en dos grupos generales: tareas
administrativas comunes ejecutndose a intervalos regulares o tareas especializadas que
necesitan ejecutarse en una hora nica. Las tareas nicas se ejecutan como entradas en el
archivo /etc/crontab, como se describe en la siguiente seccin. Las tareas administrativas
comunes, aunque se ejecuten desde el archivo /etc/crontab, estn mejor organizadas en
directorios cron especializados. En estos directorios, cada tarea se coloca en su propia
secuencia de comandos shell invocando la tarea cuando se ejecuta. Por ejemplo, pueden
existir varias tareas administrativas que necesitan ejecutarse cada semana, el mismo da, como
cuando se programa el mantenimiento del sistema el domingo por la maana. Para este tipo de
tareas, cron ofrece varios directorios especializados para tareas automticas diarias,
semanales, mensuales o anuales. Cada una contiene un prefijo cron y un sufijo para el
intervalo. El directorio /etc/cron.daily se usa para tareas realizadas a diario, mientras las
tareas semanales se colocan en el directorio /etc/cron.weekly. Los directorios de cron se
muestran en la siguiente tabla.

53
Ejecucin de secuencias de comandos de directorio de cron
Cada directorio contiene secuencias de comandos y todas se ejecutan simultneamente.
La programacin para cada grupo se determina con una entrada en el archivo /etc/crontab. La
ejecucin real de secuencias de comandos se realiza por secuencia de comandos
/usr/bin/run-parts, que ejecuta todas las secuencias de comandos y programas de un
directorio determinado. La programacin de todas las tareas de un directorio especfico se
maneja con una entrada en el archivo /etc/crontab. Linux ofrece entradas con horas
designadas, que puede cambiar de acuerdo con sus necesidades. Aqu se muestra el archivo
crontab, con horas para ejecutar las secuencias de comandos en diferentes directorios cron.
Aqu se ve que la mayora de secuencias de comandos se ejecutan a las 4 a.m., ya sea diario
(4:02), el domingo (4:22) o el primer da de cada mes (4:42).
Las secuencias de comandos por hora se ejecutan un minuto despus de la hora.
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

3.6. Estructuras de control

Debemos tener presente que el principal objetivo de un shell es el de ejecutar rdenes, por
tanto, cuando se diseo el constructor if se plante tomar como expresin lgica la propia
ejecucin de un programa. En este caso se considera como cierto el hecho que un programa
termine sin errores y como falso que se produzca algn error en la ejecucin del mismo.
NOTA: El cdigo de retorno de los procesos es un entero de 8 bits. Cuando este entero es cero
se considera que la ejecucin no ha encontrado ningn error. El valor de salida de la ltima
lnea de rdenes ejecutada se puede acceder en la variable $?.

En el shell podemos crear las habituales estructuras condicionales if o if-else.

54
a. If simple
Con la ayuda del condicional if podemos hacer que los scripts evalen condiciones y se
comporten de acuerdo a las necesidades de cualquier problema

Esta sera la forma de if:


if condicin; then
operaciones
fi
o tambin:
if condicin
then
operaciones
fi

Esta sera la forma del if-else


if condicin
then
operaciones
else
operaciones
fi

Este es un ejemplo de uso de condicionales if y test


#!/bin/bash
# Condicionales
VARIABLE=45
if [ ${VARIABLE} gt 0 ]; then
echo "${VARIABLE} es mayor que 0"
fi

# Podemos meter el then en la siguiente linea


if [ e /etc/shadow ]
then
echo "OK, parece que tienes un sistema con shadow pass"
fi

## Estructura ifelse
OTRA=23
if [ ${OTRA} lt 0 ]
then
echo "${OTRA} es menor que 0"
else
echo "${OTRA} es mayor que 0";

fi
## Estructura ifelseif
# Vamos a usar "read" para pedirle datos al usuario
echo n "Mete un valor: "
read VALOR1
echo n "Mete otro valor: "
read VALOR2
echo "Has introducido los valores ${VALOR1} y ${VALOR2} "
if [ ${VALOR1} gt ${VALOR2} ]
then
echo "${VALOR1} es mayor que ${VALOR2}"
elif [ ${VALOR1} lt ${VALOR2} ]
then
echo "${VALOR1} es menor que ${VALOR2}"

55
else
echo "${VALOR1} y ${VALOR2} son iguales"
fi

## Estructura test
# Ejecutar operacion si no se cumple la condicin
# test condicin || operacion
# Ejecutar operacin si se cumple
# test condicin && operacion
# Este test crea un fichero si no existe.
test f
'./fichero.txt' || touch fichero.txt

b. If Anidado

Y tambin tenemos el if-elseif...-else


if condicin
then
operaciones
elif condicin
then
operaciones
else
operaciones
fi

Comprobaciones que podemos hacer:


En las condicionales podemos hacer una serie de comprobaciones con ficheros, las mostramos
en orden alfabtico:
a fichero : verdadero si el fichero existe
e fichero : lo mismo
b fichero : verdadero si el fichero existe y tiene algn bloque especial c fichero : verdadero
si el fichero existe y es del tipo carcter (suelen ser dispositivos)
d fichero : verdadero si el fichero existe y es un directorio.
f fichero : verdadero si el fichero existe y es un fichero comn.
g fichero : verdadero si el fichero existe y tiene el bit setGruopID establecido
h fichero : verdadero si el fichero existe y es un enlace smbolico
k fichero : verdadero si el fichero existe y tiene el sticky bit establecido
p fichero : verdadero si el fichero existe y es una tubera con nombre.
r fichero : verdadero si el fichero existe y tiene permisos de lectura.
s fichero : verdadero si el fichero existe y es mayor que 0.
u fichero : verdadero si el fichero existe y tiene el bit setUID establecido.
w fichero : verdadero si el fichero existe y tiene permisos de escritura.
x fichero : verdadero si el fichero existe y tiene permisos de ejecucin .
O fichero : verdadero si el fichero existe y el EUID es de nuetro usuario.
G fichero : verdadero si el fichero existe y el EGID es de nuestro grupo.
L fichero : verdadero si el fichero existe y es un enalce simblico.
S fichero : verdadero si el fichero existe y es un socket.
N fichero : verdadero si el fichero existe y ha cambiado tras la ltima lectura.
t descriptor : verdadero si en un descriptor de fichero abierto y un terminal

A partir de ah podemos hacer las comprobaciones tan complejas como haga falta:
#!/bin/sh
# script para comprobar si un fichero existe. Espera un parmetro
if [ e $1 ] && [ f $1 ]
then

56
echo "OK, el fichero existe "
else echo "NO existe"
fi

# Para comprobar la negacin usaramos el smbolo: !


if [ ! e $1 ]
then
echo No existe
fi

Otros test que podemos hacer comparando ficheros:


fichero1 nt fichero2 : verdadero si fichero1 es ms reciente que fichero2 o si el fichero1 existe
y el otro no.
fichero1 ot fichero2: verdadero si fichero1 es ms viejo que fichero2 o si el fichero1 existe y el
otro no.
fichero1 ef fichero2: verdadero si los dos comparten el mismo nmero de inodo y dispositivo.

case
En programacin muchas veces es necesario comprobar el valor de una variable con case y
validar si coincide con algn valor esperado, esto es posible solucionarlo con el if pero cuando
son muchas las posibles opciones a evaluar es mejor la ayuda de case, evitando escribir tantos
if.
El case o el switch-case tan tpico del lenguaje C tambin est disponible en shell.
Su estructura de uso es la siguiente:

Esta sera su forma:


case variable in
valor1)
operaciones_si_variable=valor1
;;
valor2)
operaciones_si_variable=varlo2
;;
*)
operaciones_en_cualquier_otro_caso
esac

Este es un ejemplo de uso de la estructura case


#!/bin/bash
NOMBRE=""
echo -n "Dame un nombre: "
read NOMBRE
case ${NOMBRE} in
iigo)
echo "${NOMBRE} dice: me dedico a Navarrux"
;;
sten)
echo "${NOMBRE} dice: tengo un blog friki"
;;
asier)
echo "${NOMBRE}> dice: .NET me gusta"
;;
pello)
echo "${NOMBRE}> dice: el shell mola"
;;
*)
echo "A ${NOMBRE} no lo conozco"
esac

57
3.7. Estructuras de repeticin
Adems de la sintaxis estudiada hasta ahora existen en la programacin shellscript bloques de
programa conocidos como bucles que permiten ejecutar ciclos de comandos siempre que se
cumpla una condicin. Los bucles tienen una funcin similar a la de cualquier otro lenguaje de
programacin, pero permiten que un script ejecute ciertas rdenes si se cumple una condicin,
permitiendo que el script haga lo que el programador desea. Los bucles ms utilizados son el
for y el while.

Iteraciones
Tambin tenemos las clsicas iteraciones for y while adems de otras, siempre que
necesitemos realizar tareas repetitivas, recorrer arrays o resultados de comandos, etc...

for
La sentencia for repite una serie de rdenes (repetir cierto nmero de veces las declaraciones
especificadas) a la vez que una variable de control va tomando los sucesivos valores indicado
por una lista de cadenas de texto. Para cada iteracin la variable de control toma el valor de
uno de los elementos de la lista.
Se puede hacer un for de distintas maneras. El ms simple tiene esta forma:
for var in lista
do
operaciones
done

Variable (var) es el nombre que tendr la variable que controlara el ciclo, esta variable
no est precedida de $.
lista-elementos (lista) contiene la lista de elementos a recorrer, esta lista puede ser una
variable que contenga dichos elementos y estar precedida de $. En cada iteracin del
bucle la variable de control variable toma el valor del siguiente campo y se ejecuta la
secuencia de mandatos operaciones.
Los comandos se ejecutaran tantas veces dependiendo del nmero de elementos de la
lista.

Aunque se pueden crear los tpicos for que se inicializan con un valor y se hacen ejecutar x
veces. Mejor verlo en cdigo:
Ejemplo:
for i in $*
do
echo $i
done
y mostraramos todos los parmetros posicionales.
for i in *
do
echo $i
done
y mostraramos la lista de ficheros del directorio activo.

Este es otro ejemplo de uso de la iteracin for:


#!/bin/bash
## un for simple
echo "FOR simple: "
for i in a b c d e f g h i
do
echo "letra: $i"
done

58
for x in 1 2 3 4 5 6 7 8
do
echo $x
done

## for para recorrer array


NOMBRES="Iigo Sten Asier Pello Roberto"
echo "FOR simple para recorrer un array: "

echo "Participantes en la 4party: "


for i in ${NOMBRES}
do
echo ${i}
done

## for con el resultado de un comando


echo "FOR con el resultado de un comando"
for i in `cat direcciones.txt`
do
echo ${i}
done

## for con un grupo de ficheros


echo "FOR con ficheros"
for i in *.sh
do
ls lh
${i}
done

## for clsico con un ndice


echo "FOR clsico "
for (( cont=0 ; ${cont} < 10 ; cont=`expr $cont + 1` ))
do
echo "Ahora valgo> ${cont}"
done

Sentencias breay continue


La sentencia break se utiliza para terminar la ejecucin de un bucle while o for. Es decir el
control continuar por la siguiente instruccin del bucle. Si existen varios bucles anidados,
break terminar la ejecucin del ltimo que se ha abierto.

Es posible salir de n niveles de bucle mediante la instruccin break n.

La instruccin continue reinicia el bucle con la prxima iteracin dejando de ejecutar cualquier
orden posterior en la iteracin en curso

while
Otro bucle utilizado en la programacin shellscript es el ciclo while, este se utiliza para que se
ejecuten una serie de comandos o instrucciones si se cumple una determinada condicin.
Muchas veces nos interesa una iteracin sin un nmero de vueltas fijo, que simplemente
dependa de una condicin. Eso lo podemos conseguir con el while, cuya forma resumida es
esta:
while condicin
do
operaciones
done

59
Para entender mejor el funcionamiento del while realizaremos un pequeo script que repita
varias veces un mensaje pasado como argumento. La cantidad de veces que se repetir el
mensaje tambin sea pasada como argumento.
#!/bin/bash
cantidad=$1
mensaje=$2
contador=1
if [ $# -ne 2 ]; then
echo "Se necesita los parmetros <cantidad> <mensaje>"
echo "Uso: $0 <cantidad> <mensaje>"
exit
fi
while [ $contador -le $cantidad ]; do
echo $mensaje
contador=`expr $contador + 1`
done

En las lneas 2 y 3 se capturan los valores de los argumentos: cantidad de veces a


repetir y el mensaje respectivamente.
La lnea 4 se inicia una variable contador en uno, para controlar el ciclo while.
En la lnea 5 se valida que se pasen los dos parmetros requeridos (la cantidad y el
mensaje), de lo contrario en las lneas 6 y 7 se muestra la forma de uso del comando.
La lnea 10 evala de que el contador sea menor o igual que la cantidad de veces a
repetir el mensaje.
Si se cumple la condicin anterior la lnea 11 manda a escribir el mensaje tantas veces
sea necesario. La lnea 12 incrementa el contador en uno cada vez que se entra al
ciclo.

Este es un ejemplo de uso de la iteracin while:


#!/bin/bash
## Estructura while
echo "WHILE en marcha"
cont=0
# Un bucle que terminar cuando $cont sea mayor que 100
while (test ${cont} lt 100)
do
cont=`expr $cont + 10`
echo "Valor del contador: ${cont}"
done
echo "Valor final del contador: ${cont}"

## Un while infinito
# while true; do comando; done

until
Until es similar a while, salvo que su ejecucin se detiene de forma inversa. Cuando la
condicin resulta falsa, termina el bucle. Esta es su forma:
until condicin
do
operaciones
done

Este es un ejemplo de uso de la iteracin until:


#!/bin/bash
## El bucle until
# Un bucle until se ejecuta hasta que el test resulte falso
echo "Estructura until"
cont=15

60
until (test ${cont} lt 0)
do
cont=`expr $cont 1`
echo "Valor del contador: ${cont}"
done
echo "Valor final del contador: ${cont}"

select
Mediante select podemos crear mens de seleccin de manera muy cmoda. Podemos definir
un array con todas las opciones y select las mostrar por nosotros. Esta es su forma general:
select variable in lista
do
operaciones
done

Este es un ejemplo de uso de la iteracin select


#!/bin/bash
## Estructura select
# El select es similar al choice de msdos
# sirve para crear menus de seleccion
echo "Select de distros"
DISTROS="Debian Ubuntu Navarrux Gentoo Mandriva"
echo "Selecciona la mejor opcin por favor: ${resultado}"
select resultado in ${DISTROS}
do
# Si la longitud de cadena de resultado es > 0 ya est seleccionado
(test ${#resultado} ne 0 ) && break
echo "Selecciona la mejor opcin por favor: ${resultado}"
done
echo "Sistema seleccionado: [${resultado}] longitud de cadena: ${#resultado}"

Ejemplo 2:
A continuacin un pequeo script poniendo en prctica el paso de parmetro especial visto
lneas arriba con ciclo de repeticin:

#!/bin/bash
# muestra_param_2.sh

# Mostrar el nombre del script


echo "El nombre de mi script es: $0"
# Mostrar el nmero de parametros
echo "Has pasado $# paramtros"
# Lista de parmetros (un solo argumento)
for param in "$*"
do
echo "Aqu la lista de parmetros (un solo argumento) : $param"
done
# Lista de parmetros (un parmetro por argumento)
echo "Aqu la lista de parmetros (un parmetro por argumento) :"
for param in "$@"
do
echo -e "\tParmetro : $param"
done
# Mostrar el proceso
echo "El PID del shell que ejecuta el script es: $$"
# Ejecucin de un comando en segundo plano
sleep 100 &
# Mostrar el proceso ejecutado en segundo plano
echo "El PID del ultimo comando ejecutado en segundo plano es: $!"
# Mostrar el cdigo de retorno del ltimo comando "echo"

61
echo "El cdigo de retorno del comando anterior es: $?"
# Generacin de un error
echo "Generacin de un error..."
# Mostrar el comando errado
echo "ls /etc/password 2>/dev/null"
ls /etc/password 2>/dev/null
# Mostrar el cdigo de retorno del ltimo comando
echo "El cdigo de retorno del comando precedente es: $?"
exit

Lo que resulta con la siguiente invocacin:

./muestra_param_2.sh 1 2 3 cuatro 5 seis

El nombre de mi script es: ./muestra_param_2.sh


Has pasado 6 parmetros
Esta es la lista de parmetros (un solo argumento): 1 2 3 cuatro 5 seis
Esta es la lista de parmetros (un parmetro por argumento) :
Parmetro: 1
Parmetro: 2
Parmetro: 3
Parmetro: cuatro
Parmetro: 5
Parmetro: seis
El PID del shell que ejecuta el script es: 6165
El PID del ltimo comando ejecutado en segundo plano es: 6166
El cdigo de retorno del comando precedente es: 0
Generacin de error...
ls /etc/password 2>/dev/null
El cdigo de retorno del comando precedente es: 1

3.8. Funciones en el Shell

Para estructurar mejor el cdigo, dividir las partes complicadas e incluso reutilizar
funcionalidades podemos crear. Las funciones de shell pueden recibir parmetros con las
variables especiales $1, $2, ...

Aqu vemos varios ejemplos de funciones


#!/bin/bash
## funciones
# Antes que nada hay que definir las funciones, si no dara error
# las funciones toman los parmetros con $numero, como el script
# variable
RESULTADO=0

# Una funcin que muestra valores por pantalla


muestrapantalla () {
echo "Valores: $0> $1 y $2 y $3"
}

# Puede usarse return pero solo para devolver nmeros


sumame () {
echo "Estamos en la funcin: ${FUNCNAME}"
echo "Parametros: $1 y $2"
RESULTADO=`expr ${1} + ${2}`
return 0
}

# Es posible la funcin recursiva

62
boom () {
echo "No ejecutes esto... "
boom
}

# La llamada de se puede hacer as, sin parntesis


muestrapantalla 3 4 "epa"

# Llamamos a la funcin y si devuelve 0 es correcto.


sumame 45 67 && echo "OK" || echo "Ocurri un error"
echo "Resultado: ${RESULTADO} $!"

Libreras
A la hora de programar scripts de shell no es que existan herramientas para declarar libreras,
pero se pueden simular de cierta manera metiendo cdigo de funciones en ficheros de scripts
separados.

Este sera un ejemplo de uso de libreras, usando un fichero con las funciones mostradas
anteriormente:
#!/bin/bash
# No es que existan las libreras pero se puede simular
# algo similar
# Esta es la forma de importar funciones
source libreria.sh
muestrapantalla 69 123 "epa"
sumame 1337 3389 && echo "OK" || echo "Ocurri un error"
echo "Resultado: ${RESULTADO} $!"

Seales
Las seales son un mtodo de los sistemas linux para intercomunicar procesos. Las seales
ms frecuentes usadas por los usuarios son las de cancelar y matar procesos. Pero hay ms y
los procesos linux son capaces de capturar las seales para modificar su comportamiento.
Desde un script de shell tambin se pueden capturar las seales.
Este sera un simple ejemplo de la captura de seales:
#!/bin/bash
# seales
funcion () {
echo "Se ha recibido una seal: ${FUNCNAME} ${0}"
#exit
}

# Lo primero es establecer que seales se atraparn. Lo hacemos con trap


# Con esto evitaremos que se haga caso a CtrlC
CTRLZ
# trap ":" INT QUIT TSTP
# Esto es similar pero al recibir la seal dirigimos la ejecucin a la funcin
trap "funcion" INT QUIT TSTP
# Un bucle sin fin para probar
while true
do
sleep 2

echo "ufff qu sueo..."


done

3.9 Otras operaciones

63
arrays
Como ya se ha dicho, existe la posibilidad de declarar y usar arrays. Son algo
limitados pero pueden resultar prcticos.
Este es un ejemplo de uso de arrays
#!/bin/bash
# Muestra el uso de arrays
# Podemos crear arrays de una dimensin
asociaciones[0]="Gruslin"
asociaciones[1]="Hackresi"
asociaciones[2]="NavarradotNET"
asociaciones[3]="Riberlug"
# Otra forma de definirlos
partidos=("UPN" "PSN" "CDN" "IUN" "Nafarroa BAI" "RCN" )
numeros=(15 23 45 42 23 1337 23 666 69)
echo ${asociaciones[0]} es una asociacin, ${partidos[1]} un partido
#echo "Tamao: $#asociaciones"
#echo "Tamao: ${$#{partidos}}"

Operaciones
Ya que tenemos variables, que menos que poder operar con ellas de alguna forma, Al igual que
en cualquier otro lenguaje de programacin disponemos de operadores aritmticos y lgicos,
aunque su uso no es tan simple.

Aritmticas

El shell provee un mecanismo para realizar aritmtica de enteros bsica llamado "expansin
aritmtica". Este tipo de expansin no est disponible en shells ms antiguos (como Bourne
shell, donde se tiene que utilizar el comando expr que veremos ms adelante).
La expansin aritmtica est basada en un estndar POSIX, as que es posible encontrar esta
caracterstica en la mayora de shells modernos.

El formato para la expansin aritmtica es:


$((expresion))

En donde expresin es cualquier expresin matemtica que puede usar variables de Shell (que
contengan valores numricos), operadores y/o valores numricos especficos.
El resultado del clculo de la expresin es regresado en la lnea de comando, por ejemplo:
echo $((i+1))
Adiciona uno al valor de la variable i y despliega el resultado, hay que notar que la variable i no
tiene que ser precedida por el signo de pesos ($). Esto es porque el shell sabe que las nicas
cuestiones validas en una expansin aritmtica son valores, variables y operadores (+ - * /), al
evaluar el carcter i y definir que no es un valor numrico (0 a 9) ni un operador matemtico,
entonces seguramente es una variable.
Si la variable no ha sido definida o su valor es nulo (contiene una cadena nula, espacios o
valores alfanumricos) se define que el valor de la variable es cero. Por ejemplo, aun cuando
no hemos definido la variable Z ni asignado ningn valor a la misma, aun se puede utilizar en
una expansin aritmtica:

$echo $((Z+10))
10
$
o en la siguiente:
$ echo $((Z=Z+1))
1$
Ahora Z contiene el valor 1.

Este es un ejemplo del uso de operaciones aritmticas


#!/bin/bash
# ,+, *, /, %, **, variable++, variable,variable,++variable
# == : igualdad

64
# != : desigualdad
# Pruebas
VALOR1=23
VALOR2=45
# Para las operaciones puede usarse expr o []
RESULTADO=`expr ${VALOR1} + ${VALOR2}`
echo "Resultado: ${RESULTADO}"
RESULTADO=`expr ${VALOR1} + ${VALOR2} + 3`
echo "Resultado: ${RESULTADO}"
VALOR1=5
VALOR2=4
echo "${VALOR1} y ${VALOR2}"
RESULTADO=$[${VALOR1} + ${VALOR2} + 2]
echo "Ahora: ${VALOR1} + ${VALOR2} + 2 = ${RESULTADO}"
RESULTADO=$[${VALOR1} + $[${VALOR2} * 3]]
echo "Ahora: ${VALOR1} + ${VALOR2} * 3 = ${RESULTADO}"

Lgicas
Este es un ejemplo de uso de operaciones lgicas
#!/bin/bash
## operaciones lgicas
# && : and
# || : or
# ! : not
booleano=true
# Si la variable booleano es true veremos por pantalla "OK"
$booleano && echo "OK" || echo "no es true"
otrobool=!${booleano}

test ${otrobool} || echo "Ahora es falso"


# Mediante && podemos encadenar comandos
#who && ps axf
&& echo "OK"
## comparaciones : eq,ne,lt, le, gt, or ge
valor=6
test $valor le
6 && echo "Se cumple"
# Asignaciones
nuevo=${valor}
test ${nuevo} eq
${valor} && echo "Son los mismo"
echo "Ahora ${nuevo} es lo mismo que ${valor}"

Operadores de comparacin de cadenas


S1 = s2
s1 coincide con s2
s1 != s2
s1 no coincide con s2
s1 < s2
s1 es alfabticamente anterior a s2, con el local actual
s1 > s2 es alfabticamente posterior a s2, con el local actual
-n s1
s1 no es nulo (contiene uno o ms caracteres)
-z s1
si es nulo

Expresiones regulares
Una expresin regular es un patrn que describe un conjunto de cadenas y que se puede
utilizar para bsquedas dentro de una cadena o un archivo. Un usuario avanzado o un
administrador del sistema que desee obtener la mxima potencia de ciertas rdenes, debe
conocer y manejar expresiones regulares. Las expresiones regulares se construyen de forma
similar a las expresiones aritmticas, utilizando diversos operadores para combinar expresiones

65
ms sencillas. Las piezas fundamentales para la construccin de expresiones regulares son las
que representan a un carcter simple. La mayora de los caracteres, incluyendo las letras y los
dgitos, se consideran expresiones regulares que se representan a s mismos. Para comparar
con el carcter asterisco (*), ste debe ir entre comillas simples ('*').

En las expresiones regulares se puede utilizar una barra inclinada invertida (\), denominada a
veces como barra de escape, para modificar la forma en la que se interpretar el carcter que
le siga. Cuando los metacaracteres ?, +, {, }, |, ( y ) aparecen en una expresin
regular no tienen un significado especial, salvo que vayan precedidos de una barra de escape;
si se utilizan anteponiendo esa barra, es decir \?, \+, \{, \}, \|, \( o \), su significado
ser el que corresponda segn la Tabla.

Ejemplo: Buscar en el archivo /etc/group las lneas que contengan un carcter k, o y o z:


$ grep [kyz] /etc/group

66
El siguiente ejemplo permite aadir a la variable $PATH un directorio que se pase como primer
argumento del guion; si se da la opcin after como segundo argumento del guion, el directorio
se aadir al final de la variable $PATH, en cualquier otro caso el directorio se aadir al
principio de $PATH:
#!/bin/bash
# Uso: pathmas directorio [after]
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
else
echo "$1 ya est en el path"
fi

Referencias

TLDP-ES/LuCAS http://es.tldp.org/
Comandos Linux unix y programacin Shell. Taller Shell, comandos y programacin.

Historia de los Shell. http://fpg.hol.es/GNU-Linux/un_poco_de_historia_gnulinux.html

El Shell de UNIX. http://bioinf.comav.upv.es/courses/linux/unix/shell.html

Introduccin al Shell script. http://enavas.blogspot.com/2008/01/introduccin-shell-


scripts-con-bash.html

Taller Introduccin a Linux. TOMADO DE: http://tallergnulinux.sourceforge.net/

http://linux.ciberaula.com/articulo/linux_cron/

Ubuntu. http://www.guia-ubuntu.com/index.php/Terminal

Shell script en Ubuntu http://doc.ubuntu-es.org/Script

67

Das könnte Ihnen auch gefallen