Está en la página 1de 64

Programacin en SHELL

( Bash )
Que es una shell ?
El shell de Unix o tambin shell, es el termino usado en informtica para referirse a un interprete de
comandos. Los comandos que aportan los intrpretes, pueden usarse a modo de guin si se escriben
en ficheros e!ecutables denominados shell-scripts, de este modo, cuando el usuario necesita hacer
uso de "arios comandos o combinados de comandos con herramientas, escribe en un fichero de
texto marcado como e!ecutable, las operaciones que posteriormente, l#nea por l#nea, el intrprete
traducir al n$cleo para que las realice.
%in ser un shell estrictamente un lengua!e de programacin, al proceso de crear scripts de shell se
le denomina programacin shell o en ingls, shell programming o shell scripting.
Los usuarios de Unix & similares, pueden elegir entre distintos shells 'programa que se deber#a
e!ecutar cuando inician la sesin, bash, ash, csh, (sh, )sh, tcsh*.
El trmino shell tambin hace referencia a un programa particular, tal como el Bourne shell, sh. El
Bourne shell fue el shell usado en las primeras "ersiones de Unix & se con"irti en un estndar+
todos los sistemas similares a Unix tienen al menos un shell compatible con el Bourne shell. El
programa Bourne shell se encuentra dentro de la !erarqu#a de archi"os de Unix en /bin/sh. En
algunos sistemas, tal como BSD, /bin/sh es un Bourne shell o un equi"alente, pero en otros
sistemas como muchas distribuciones de Linux, /bin/sh es un enlace simblico a un shell
compatible con ms caracter#sticas 'como Bash*. PS!" especifica su shell estndar como un
subcon!unto estricto del #orn shell.
,rimeros pasos
Uno de los primeros pasos es saber que shell 'interprete de comando estamos usando*.
$ echo $SHELL
/bin/bash
Las "ariables por con"encin se utili(a en ma&$sculas & las forma de obtener el contenido de la
"ariable o me!or dicho su "alor es poniendo el s#mbolo $.
%i queremos saber la "ersin de nuestro interprete de comandos en este caso bash e!ecutamos el
siguiente comando -
$ echo $B%SH&'E(S!)
4.1.5(1)-release
,ara conocer todos los interpretes de comandos que tenemos "eremos que se guardan dentro de un
archi"o llamado shells.
$ cat /etc/shells
/bin/csh
/bin/sh
/bin/ksh
/bin/tcsh
/bin/dash
/bin/bash
%i queremos cambiar nuestro shell por defecto a bash e!ecutamos el siguiente comando & luego
"ol"emos a loguearno para que tome la nue"a configuracin.
$ chsh -s /bin/bash
.ane!o de comodines
Los comodines de b$squeda son signos o s#mbolos que nos a&udarn a la hora de encontrar alg$n
archi"o en nuestro ordenador. /onde mas lo podemos llegar a utili(ar es con el comando ls.
$ ls /bin/bash
0c tenemos una tabla con los distintos comodines & su explicacin.
*omo+,n Descripcin
? Uno o slo un carcter.
1 2ero o ms caracteres.
3con!unto4 Uno los caracteres de conjunto.
35con!unto4 Un carcter que no este en conjunto.
E!emplo de usos -
$ ls -.txt
En el e!emplo anterior me trae cualquier archi"o que tenga como extensin txt.
$ ls /bin/l/
/bin/ln /bin/ls
El tercer comod#n permite indicar un con!unto de caracteres que son "lidos. ,or e!emplo l0eno1-
encontrara el fichero less lesssecho less2ile less3e4 lesspipe ln loa+3e4s login no traira liss. Es
decir como primer letra si o si l a continuacin puede ser e, n o o & luego como bien di!imos el
comod#n '1* representa cero o ms caracteres reali(a una distributi"a.
$ ls /bin/l0eno1-
/bin/less /bin/lessecho /bin/lessfile /bin/lesskey /bin/lesspipe /bin/ln /bin/loadkeys /bin/login
El comod #n tilde
Este comod#n es 5 que se utili(a para referirse al home de los usuarios, por e!emplo 5pablo se
refiere a /home/pablo.
$ ls -a 5pablo
./ ../ .bash_logout .bash_profile .bashrc
El comod #n lla"es
Este comod#n a comparacin de los otros, no estudia el nombre de los ficheros existentes en disco
para nada, simplemente expande una palabra por cada una de las cadenas de caracteres que
contiene, por e!emplo -
$ echo c6ami7ontamina78on
camion cantaminaon con
Lo que reali(a es una distribucin c-9ami-9on, c-9ontaminaon & c-9con, al poner 78 lo que hace es
poder formar la palabra con es decir como luego de la 7 no ha& nada puede formar otra palabra con
on.
6eamos un e!emplo mas comple!o que a7ade mas lla"es -
$ echo c6a6mi7nt8a7ose8r
caminar cantar coser
%iempre combina c-9a & luego con 6mi7nt8 luego con a & la r & por ultimo combina c-9ose-9r
%e puede usar dos puntos '..* para hacer algo similar a lo que hacen los corchetes es decir indicar un rango.
,or e!emplo -
$ echo l6a..:8
la lb lc ld le lf lg lh li lj
Las lla"es deben tener al menos dos cadenas, el siguiente e!emplo "emos que esto no sucede.
$ echo ca6a8sa
caa!sa
2omodines extendidos
Bash permite usar un con!unto de comodines extendidos, pero para poder usarlos debemos de
acti"ar la opcin ext_glob de Bash.
,ara fi!ar estos "alores usamos el comando shopt 'shell option*, si e!ecutamos el comando shopt
"eremos la lista de "ariables que podemos modificar.
$ shopt
autocd off
cdable_"ars off
cdspell off
checkhash off
checkjobs off
check#insi$e on
cmdhist on
compat%1 off
compat%& off
compat4' off
dirspell off
dotglob off
e(ecfail off
e(pand_aliases on
e(tdebug off
e(tglob on
e(t)uote on
failglob off
force_fignore on
globstar off
gnu_errfmt off
histappend on
histreedit off
hist"erify off
hostcomplete off
hupone(it off
interacti"e_comments on
lithist off
login_shell off
mail#arn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
prompt"ars on
restricted_shell off
shift_"erbose off
sourcepath on
(pg_echo off
8odas estas "ariables son booleanas que contienen el "alor on9off, para acti"arlo usamos el
comando shopt -s opcion & para desacti"arlo shopt -u opcion.
6emos en la tabla algunas de esa opciones con ma&or detalle de lo que hace -
pcin Descripcin
cdable:"ars ,ermite que cd use los "alores de las "ariables como nombres de directorios.
cdspell ;gnora peque7os errores en los cambios de directorio con cd. %lo en la e!ecucin
interacti"a.
cmdhist <uarda los comandos que hemos escrito en "arias l#neas en una sola l#nea del
historial.
dotglob ;nclu&e en la expansin de comodines los ficheros que empie(an por '.*.
expand:aliases Expande un alias cuando lo e!ecuta.
extglob Utili(a extensiones de los comodines.
failglob %i falla la expansin de un comod#n porque no encuentra nada falla el comando
'como hace el C shell*.
force:fignore Los sufi!os especificados en la "ariable de entorno FIGNORE no se usan para
completar palabras con tabulador.
hostcomplete %e intenta completar nombres de host al pulsar tabulador cuando la palabra
contiene una @.
interacti"e:comments ,ermite que dentro de un comando de sesin interacti"a ha&a comentarios
'precedidos por *.
login:shell 6ariable de slo lectura que indica si =ash ha sido lan(ado como un shell de login.
nocaseglob ;ndica si los comodines expanden sin sensibilidad a ma&$sculas9min$sculas. >o
confundir con la "ariable completion-ignore-case de inputrc que lo que hac#a era
expandir con tabuladores.
nullglob ?ace que cuando un patrn no encuentra ficheros, se expandan por la cadena "ac#a
en "e( de por el patrn sin expandir.
sourcepath ?ace que el comando interno source busque el argumento en los directorios que
indique !"#$.
E!emplo -
$ export D*;/usr/share/+oc
$ shopt -s c+able&<ars
$ c+ D*
La opcin cdable_%ars permite que el comando cd pueda utili(ar "ariables como nombres de
directorios. @bser"amos que &OC al utili(arlo con el comando cd no "a precedido por '.
$ shopt -s extglob
2on esta opcin podemos utili(ar uno de estos cinco nue"os tipos de patrones-
?'patternAlist* 2ero o una ocurrencia de pattern-list.
1'patternAlist* 2ero o ms ocurrencias de pattern-list.
B'patternAlist* Una o ms ocurrencias de pattern-list.
C'patternAlist* Exactamente uno de los patrones de la lista.
5'patternAlist* 2ualquier cosa excepto uno de los patrones de la lista.
$ ls -l /bin/l/
-r#(r-(r-( 1 root root 4*+&' abr &* &'1' /bin/ln
-r#(r-(r-( 1 root root 1'*''* abr &* &'1' /bin/ls
E!emplo donde solo listo que coincida con ( o ).
$ touch carta6=..>8.txt
$ ls carta?(0=..>1).txt
carta'.t(t carta+.t(t
E!emplo donde listo el rango de ( a ).
$ touch carta6=..>8.txt
$ ls carta?(0=->1).txt
carta'.t(t carta1.t(t carta&.t(t carta%.t(t carta4.t(t carta5.t(t carta,.t(t carta-.t(t carta*.t(t
carta+.t(t
%i queremos buscar los archi"os que solo tengan extensin *c, *h & *o reali(amos lo siguiente -
$ touch e:emplo6c7h7o7cpp8.txt
$ ls -.0cho1
ejemplo.c ejemplo.h ejemplo.o
6emos que en el e!emplo anterior solamente me trae las extensiones que contengan solo un carcter
'+*c, +*h & +*o*, el corchetes ,- slo permite acepta un carcter. %i quiero traer los que tengan
extensin *cpp no se podr. En cambio con el siguiente e!emplo si podemos -
$ touch e:emplo6c7h7o7cpp8.txt
$ ls -.@(cAoAhAcpp)
ejemplo.c ejemplo.cpp ejemplo.h ejemplo.o
2on el pipe 'D* reali(a un or 'o* que coincida con algunos de los patrones correspondientes lo que
me permite a7adir patrones.
El e!emplo anterior es equi"alente a -
$ ls @(-.cA-.oA-.hA-.cpp)
ejemplo.c ejemplo.cpp ejemplo.h ejemplo.o
%i quiero listar lo que no sea con extensin +*c, +*o, +*h & +*cpp reali(o la muestra con el patrn .
$ ls B(-.cA-.oA-.hA-.cpp)
carta'.t(t carta1.t(t carta&.t(t carta%.t(t carta4.t(t carta5.t(t carta,.t(t carta-.t(t carta*.t(t
carta+.t(t
%i quiero borrar todos los archi"os excepto los que empie(an con papel0=->1.txt reali(o lo
siguiente -
$ touch carta6=..>8.txt
$ touch papel6=..>8.txt
$ rm -< B(papel?(0=->1)).txt
.carta'.t(t/ borrado
.carta1.t(t/ borrado
.carta&.t(t/ borrado
.carta%.t(t/ borrado
.carta4.t(t/ borrado
.carta5.t(t/ borrado
.carta,.t(t/ borrado
.carta-.t(t/ borrado
.carta*.t(t/ borrado
.carta+.t(t/ borrado
2omandos internos de =ash
=ash siempre busca los programas que e!ecutamos en los directorios indicados en la "ariable de
entorno '!"#$, pero ha& ciertos comandos internos de bash que no corresponde a ning$n archi"o
del disco, algunos de estos comandos son cd, chdir, alias, set o export0 etc.
,ara saber los comandos que tenemos en bash e!ecutamos help.
$ help
$ help alias
alias1 alias 2-p3 2name24"alue3 ... 3
5efine o muestra aliases.

6alias7 sin argumentos muestra la lista de aliases en la forma
reutili$able 6alias 89:;<=4>?@9<7 en la salida estAndar.

5e otra manera0 se define un alias por cada 89:;<= cuyo >?@9< se
proporcione. Bn espacio final en >?@9< causa )ue se re"ise
la siguiente palabra para sustituciCn de alias cuando se e(pande
el alias.

9pciones1
-p :uestra todos los aliases definidos en un formato reusable

=stado de salida1
alias de"uel"e "erdadero a menos )ue se de un 89:;<= para el cual
no se haya definido ningDn alias.
2aracteres especiales & entrecomillado
Los caracteres /,0, 1, 2, +, 3, 4, ,, -, 5, 6 son e!emplos de caracteres especiales de =ash que &a hemos "isto
en cap#tulos anteriores.
Car7cter &escripci8n
E /irectorio home.
F %ustitucin de comando.
G 2omentario.
H 6ariable.
I ,roceso en bac)ground.
+ %eparador de directorios.
1 2omod#n = a n carcter.
? 2omod#n de un slo carcter.
9 %epardor de directorios.
' Empe(ar un subshell.
* 8erminar un subshell.
J 2arcter de escape.
K Ledirigir la entrada.
M Ledirigir la salida.
D ,ipe.
3 Empie(a con!unto de caracteres comod#n.
4 0caba con!unto de caracteres comod#n.
N Empie(a un bloque de comando.
O 0caba un bloque de comando.
P Entrecomillado fuerte.
Q Entrecomillado dbil.
5 >o lgico de cdigo de terminacin.
2aracteres de escape
@tra forma de cambiar el significado de un carcter de escape es precederlo por 9, que es lo que se llama el
car7cter de escape.
,or e!emplo -
$ echo CD-DED9F es una expresion cierta
&E%F5 es una e(presion cierta
/onde hemos puesto el carcter de escape a los caracteres especiales para que =ash no los interprete.
8ambin lo usamos para que poder usar los espacios a los nombres de ficheros, &a que el espacio es
interpretado por =ash como un separador de argumentos de la l#nea de comandos.
$ echo GHola Hun+oI 9 e:emploD espacio.txt
$ cat e:emploD espacio.txt
Entrecomillar los entrecomilla+os
,odemos usar el carcter de escape para que no se interpreten los entrecomillados simples o dobles, es decir-
$ echo DICD-DED9FDI es una expresion cierta
G&E%F5G es una e(presion cierta
$ echo DJCD-DED9FDJ es una expresion cierta
7&E%F57 es una e(presion cierta
Kexto +e <arias l,neas
=ash nos permite utili(ar el carcter de escape para ignorar los retornos de carro de la siguiente forma -
$ echo Esto es una prueba D
9 +e <arias lineas D
9 linea L D
9 linea C
=sto es una prueba de "arias lineas linea 1 linea &
0l poner el carcter D & darle enter en la siguiente linea nos pone 9, & nos permite seguir escribiendo.
@tro e!emplo es usando las comillas simples P al principio & al final, en "e( de usar D.
$ echo JEsto es una prueba
9 +e <arias lineas
9 linea L
9 linea CJ
=sto es una prueba de "arias lineas linea 1 linea &
'er historial +e coman+os
,ara "er el historial de los comandos que e!ecutamos hab#amos "isto que existe el comando histor:, tambin
encontramos el comando fc 'fix command* es un clsico del C ;hell tra#do al mundo de =ash, que al igual
que el comando histor: lee el archi"o *bash_histor:.
2omo di!imos anteriormente estos comandos internos de bash no contienen man sino la forma de "er a&uda
es mediante el comando help.
$ help 2c
,odemos obtener un listado de los $ltimos comandos usados !unto con su numero usado -
$ 2c -l
Es equi"alente al comando histor: excepto que solo el comando fc muestra slo los $ltimos comandos del
historial & no todo.
,ara editar uno de ellos indicamos su n$mero -
$ 2c C=
Esto nos abrir un editor que depender de la "ariable E&I#OR cual nos habr es decir si queremos usar el
editor %i<%im exportamos la "ariable E&I#OR.
$ export ED!K(;<im
El problema de este comando que una "e( que salimos del editor e!ecuta la sentencia que modificamos.
E!ecutar comandos anteriores
0l igual que histor: podemos e!ecutar comando anteriores o por el n$mero de comando.
Comando &escripci8n
55 E!ecutar el $ltimo comando.
5n E!ecutar el comando n$mero n.
5cadena E!ecutar el $ltimo comando que empiece por cadena.
2on la opcin .cadena, &a que con dar las primeras letras de un comando que ha&amos e!ecutado
pre"iamente lo busca en el historial & lo e!ecuta, se e!ecuta el comando ms reciente que empiece por la
cadena.
Las teclas +e control +el terminal
Las teclas de control del terminal son combinaciones de teclas que interpreta el terminal 'no =ash*.
$ stt4 --all
6eremos que por e!emplo M* esto significa la tecla Ctrl=C, "eremos algunas que son $tiles-
Combinaci8n de tecla Nombre
stt:
&escripci8n
2trlBc intr ,ara el contro
2trlBJ quit Ruer(a la parada del comando actual 'usar si Ctrl=c no
responde*.
2trlBd eof Rinal del flu!o de entrada.
2trlBu )ill =orra desde la posicin actual al principio de la l#nea.
2trlBS Serase =orra desde la posicin actual al principio de la palabra.
%i queremos usar detener un programa por lo general se usa la combinaciones de las teclas Ctrl=C, esto
manda un mensa!e al programa para que pueda terminar liberando correctamente los recursos asignados. %i
por alguna ra(n no termina es decir ignora el mensa!e en"iado de Ctrl=C, siempre podemos utili(ar Ctrl=9,
el cual termina el programa sin esperar a que este libere recursos.
Ho+os +e e+icin en la l,nea +e coman+os
,or defecto >ash utili(a las teclas del modo de edicin de emacs, pero puede cambiar a las teclas del modo
de edicin de %i usando el siguiente comando -
$ set -o <i
T para "ol"er a la combinacin de teclas por defecto o utili(ar las teclas de emacs.
$ set -o emacs
Ho<erse por la l,nea
,ara mo"erse por la l#nea de edicin, borrar partes de la l#nea, ir al principio & final de la l#nea usando la
combinaciones de teclas como se muestra en la siguiente tabla.
Combinaci8n de teclas &escripci8n
2trlBa ;r al principio de la l#nea.
2trlBe ;r al final de la l#nea.
EscBb ;r una palabra hacia atrs 'bac)Sard*.
EscBf ;r una palabra hacia adelante 'forSard*.
2trlBb ;r una letra hacia atrs.
2trlBf ;r una letra hacia adelante.
2trlBu =orra de la posicin actual al principio de la l#nea.
2trlB) =orra de la posicin actual al final de la l#nea.
2trlBS =orra de la posicin actual al principio de la palabra.
EscBd =orra de la posicin actual al final de la palabra.
2trlBd =orra el carcter actual hacia adelante.
2trlB& /eshace el $ltimo borrado 'Tan)*.
Buscar 4 e:ecutar coman+os +el historial
Ta "imos como mo"ernos, & borrar, ahora si queremos buscar un determinado comando podemos usar la
combinacin de teclas Ctrl=R, que nos permite buscar hac#a atrs en el historial un comando que contenga
un determinado texto. 0l pulsar esta combinacin de teclas el prompt cambia de forma & seg$n "amos
escribiendo nos "a indicando el comando del histrico que cumple el patrn dado.
La siguiente tabla muestra la combinaciones de teclas -
Combinaci8n de teclas &escripci8n
2trlBr Leali(a una b$squeda hacia atrs 'Le"erse*.
;ntro E!ecuta el comando encontrado.
Esc ,asa a editar el comando encontrado.
2trlBg 2ancela la b$squeda & de!a limpia la l#nea de edicin.
%u tocompletar con el tabula+o r
La tecla de #ab 'tabulador* nos a&uda a completar el comando que estamos escribiendo o fichero o
directorio.
Leglas a tener en cuenta -
U. %i no ha& nada que empiece por el texto de la palabra que precede al cursor se produce un pitido que
informa del problema.
V. %i ha& un comando 'en el !"#$*, una "ariable 'siempre precedida por '*, un nombre de fichero o
funcin >ash que comien(a por el texto escrito, >ash completa la palabra.
W. %i ha& un directorio que comien(a por el nombre escrito, >ash completa el nombre de directorio
seguido por una barra de separacin de nombres de directorios 9.
X. %i ha& ms de una forma de completar la palabra el shell completa lo ms que puede & emite un
pitido informado de que no la pudo terminar de completar.
Y. 2uando >ash no puede completar una cadena 'por haber "arias posibles que empiecen igual*,
podemos pulsar dos "eces el tabulador & se nos mostrar una lista con las posibilidades cadenas
candidatas.
La librer,a rea+line
Esta librer#a permite editar l#neas de texto usando los modos emacs & %i. 0unque originalmente creada por
>ash, actualmente la utili(a miles de comandos de <>U. Esto permite estandari(ar las combinaciones de
teclas entre muchos comandos.
Readline se puede personali(ar usando ficheros de configuracin o bien asignado combinaciones de teclas
para la sesin.
El fichero de configuracin
8iene un archi"o global que debe ser colocado en <etc<inputrc, & otro para cada usuario que por defecto se
llama *inputrc & que debe ser colocado en el home de cada usuario.
2uando bash arranca lee estos ficheros 'si existen* & carga sus "alores. /entro del fichero puede haber
comentarios 'precedidos por *, combinaciones de teclas & asignaciones a "ariables de readline.
2ombinaciones de teclas
Lo primero que "eremos son las combinaciones de teclas que estn asignadas para una funcin determinada.
,ara obtener informacin podemos consultar haciendo info readline o en man bash. Estas funciones reali(an
multitud de operaciones comunes. ,ara listar estas "ariables podemos crear el fichero *inputrc en nuestro
directorio home & a7adir la siguiente entrada -
N Lista las 2unciones 4 <ariables +e rea+line
GD*-xD*-2IO +ump-2unctions
GD*-xD*-<IO +ump-<ariables
Una "e( que reali(amos estos cambios podemos o bien logearnos nue"amente para que tome efecto el
archi"o *inputrc o bien presionas las teclas Ctrl=x Ctrl=r para que readline "uel"a a leer nue"amente el
archi"o *inputrc.
0hora reali(amos la combinacin de teclas Ctrl=x Ctrl=f muestre las funciones de readline 'que e!ecuta la
funcin dump-functions?@ de readline* & Ctrl=x Ctrl=% par que muestre las "ariables de readline.
;ecuencia &escripci8n
J2A 8ecla Ctrl.
J.A 8ecla de escape '.eta*.
Je %ecuencia de escape.
JJ El carcter 9 literal.
JZ El carcter A literal.
JP El carcter B literal.
Un problema que tiene a "eces la terminal es que normalmente la teclas &EC no funciona correctamente, en
este caso necesitamos usar una secuencia de escape para hacer que esta tecla llame a la funcin delete-char?@
de readline.
N Borra con la tecla DEL
GDe0E5IO +elete-char
readline tiene una serie de "ariables, que aparecen documentadas !unto con las funciones de readline 'que
podemos consultar con la combinaciones de teclas Ctrl=x Ctrl=%*, las cuales podemos asignar un "alor en el
fichero de configuracin de readline con set.
Una "ariable interesante de readline es que al completar con tabulador distingan min$sculas de ma&$sculas.
$ m3+ir 'i+eos
$ c+ <i+ PK%B9
>os aparecer -
$ c+ 'i+eos/
,ara ello podemos a7adir la siguiente l#nea al fichero de configuracin de readline -
N !gnora +i2erencias +e ma4usculas/minusculas al
N completar con tabula+or
set completion-ignore-case on
0signacin de teclas de sesin
%i lo que queremos es probar combinaciones de teclas que no queremos almacenar de forma permanente
podemos usar el comando bind, cu&a sintaxis es similar a la del fichero de configuracin, pero tenemos que
encerrar cada asignacin entre comillas simples o dobles.
$ bin+ GDID*-xD*-gDIO +ump-2unctionsI
%i queremos "er las asignaciones de teclas que ha& hechas a cada funcin de readline podemos usar el
comando -
$ bin+ -P
@tra forma de sacar las funciones de readline -
$ bin+ -l
,odemos sacar todas las asignaciones de teclas en formato inputrc usando el comando -
$ bin+ -p
2on el comando anterior podemos en"iar la salida a un fichero para luego editarlo -
$ bin+ -p 9 .inputrc
,odemos asignar combinaciones de teclas que e!ecuten comandos con la opcin -x -
$ bin+ -x GDID*-lDIO ls -laI
0l presionar la tecla Ctrl=l e!ecutara ls -la.
Los ficheros de configuracin de =ash
2ada "e( que nos logeamos se e!ecuta el contenido del fichero <etc<profile, & luego se e!ecuta el fichero
*bash_profile de nuestro home. 2ualquier configuracin que a7adamos a *bash_profile no ser efecti"a hasta
que salgamos de la cuenta & "ol"amos a logarnos, si queremos e!ecutar los cambios que reali(amos en este
archi"o sin salir & "ol"ernos a loguear utili(amos el comando source, el cual e!ecuta el contenido del fichero
que le digamos.
$ source .bash&pro2ile
8ambin podemos usar el punto '**, con lo cual har#a lo mismo que source.
$ . .bash&pro2ile
>ash permite usar dos nombres alternati"os para *bash_profile por ra(ones de compatibilidad histrica-
*bash_login, nombre deri"ado del fichero *login del 2 %hell, & *profile nombre usado por el =ourne %hell &
el [orn %hell. En cualquier caso, slo uno de estos ficheros ser e!ecutado- %i *bash_profile existe los dems
sern ignorados, sino =ash comprueba si existe *profile. La ra(n por la que se eligi este orden de b$squeda
es que podemos almacenar en *profile opciones propias del =ourne %hell, & a7adir opciones exclusi"as de
=ash en el fichero *bash_profile seguido del comando source *profile para que =ash tambin cargue las
opciones del fichero *profile.
*bash_profile se e!ecuta slo al logarnos, si abrimos otro shell 'e!ecutando bash o su* desde la l#nea de
comandos de =ash lo que se intenta e!ecutar es el contenido de *bashrc. %i *bashrc no existe no se e!ecutan
configuraciones adicionales al abrir un nue"o shell. Este esquema nos permite separar configuraciones que se
hacen una sola "e(, al logarnos, de configuraciones que se cambian cada "e( que se abre un nue"o shell. %i
ha& configuraciones en *bashrc que tambin queremos e!ecutar al logarnos podemos poner source *bashrc
dentro del fichero *bash_profile.
,or $ltimo, el fichero *bash_logout es un fichero que, de existir, contiene ordenes que se e!ecutarn al
abandonar la cuenta, por e!emplo eliminar ficheros temporales o almacenar datos de acti"idad de usuarios en
un fichero de log.
Las <ariables +e entorno
>os a&udan a configurar el entorno en el que se e!ecutan los programas. Las "ariables de entorno no pueden
tener espacios, & si queremos asignar un "alor con espacio debemos de entrecomillarlo, o bien preceder el
espacio por un carcter de escape -
$ )HB(E;JHarcos PabloJ
$ echo $)HB(E
:arcos Hablo
$ )HB(E;HarcosD Pablo
$ echo $)HB(E
:arcos Hablo
2omo "emos para obtener el "alor de la "ariable precede del signo ', obser"amos que las comillas o el
carcter de escape no forman parte del "alor de la "ariable una "e( que se reali(a la asignacin.
,ara eliminar una "ariable de entorno usamos el comando unset.
$ unset )HB(E
Es con"eniente utili(ar los nombre de las "ariables en ma&$sculas por con"iccin.
'ariables 4 entrecomilla+o
6emos en este caso como combinar la "ariable con la salida de pantalla utili(ando el comando echo.
$ )HB(E;JHarcos PabloJ
$ ED%D;EQ
$ echo GSu nombre es O $nombre 4 la e+a+ es O $e+a+I
Iu nombre es 1 :arcos Hablo y la edad es 1 %-
PersonaliRar el prompt
,odemos personali(ar nuestro prompt de =ash usando las "ariables de entorno !;D, !;E, !;F & !;G. En la
siguiente tabla se muestra las opciones de personali(acin que podemos usar en cualquiera de los prompt.
Opci8n &escripci8n
Ja El carcter 0%2;; bell '\\]*.
J0 La hora en formato $$HII.
Jd La fecha en formato semana mes dJa.
J/ NformatoO >os permite personali(ar ms la fecha.
Je El carcter de escape 0%2;; '\WW*.
J? ?ostname.
Jh El nombre de la mquina hasta el primer punto.
J! >$mero de !obs hi!os del shell.
Jl >ombre del terminal en el que estamos traba!ando 'p.e. tt:E*.
Jn Letorno de carro & nue"a l#nea.
Jr Letorno de carro.
Js >ombre de shell.
Jt ?ora en formato $$HIIH;; con UV horas.
J8 ?ora en formato anterior pero con VX horas.
Ju >ombre de usuario.
J" 6ersin de =ash.
JS Luta del directorio actual.
J^ >ombre del directorio actual 'sin ruta*.
JG >$mero de comandos e!ecutados.
J5 >$mero histrico del comando.
JH si somos root, o ' en caso contrario.
Jnnn 2digo de carcter a mostrar en octal.
JJ La barra hac#a atrs.
J3 Empie(a una secuencia de caracteres no imprimibles, como los
caracteres de control de secuencias del terminal.
J4 0caba una secuencia de caracteres no imprimibles.
Un e!emplo sencillo es de poner 9K que es el directorio donde estamos parado & esto nos a&uda siempre para
saber donde estamos parado.
$ PSL;JDS-9J
J-F
/onde 4 significa que estamos en el directorio home.
Es mu& t#pico querer saber si somos root o cualquier otro usuario de la mquina, para lo cual se usa la opcin
9' que muestra una si somos root, o un ' en cualquier otro caso.
$ PSL;JDSD$J
4K
Es mu& com$n que accedamos a ser"idores remotos por medio de ssh o telnet & no sabes por medio del
prompt en que ser"idor estamos, para eso podemos incorporar en la "ariables !;D la opcin 9$ que nos da el
nombre de la mquina donde estamos situados, o la opcin 9h que nos da el nombre de la mquina slo hasta
el primer punto -
$ PSL;JDhDSD$J
centru(4'
$ PSL;JDHDSD$J
centru(.orgJK
2uando nos mo"emos en distintas tt& de la consola como "imos con la teclas "lt=FD hasta "lt=FL 'desde la
tt&U hasta la tt&_*, es con"eniente que en nuestro prompt tengamos tambin que tt: es donde estamos.
$ PSL;J0Du@Dh@Dl1 DSD$J
2pabloLcentru(L13 JK
2on la opcin 9u es la que indica el nombre del usuario, 9l nos indica la tt: que estamos.
8ambin podemos poner color a nuestro prompt, poniendo las secuencias de escape de caracteres no
imprimibles tienen que encerrarse ente 9,(FF, & 9-. ,ara las secuencias de escape de color, tambin deben
aparecer, seguidos adems de una m min$scula.
,or e!emplo para incluir texto a(ul en el prompt -
$ PSL;JD0D=EE0ETmD10Du@DhODS1$ J
En este caso el color a(ul esta dado por el cdigo FGm & en ning$n momento se retorna el color habitual, es
decir todo lo que escribamos sera de color a(ul para arreglar esto & que solo nuestro prompt sea de color a(ul
al final tenemos que poner ,9(FF,(m9-
' !;DMB9,9(FF,FGm9-,9u@9hH9K-' 9,9(FF,(m9-B
En la siguiente tabla tenemos los colores -
Color C8digo Color C8digo
>egro \+W\ <ris oscuro U+W\
0(ul \+WX 0(ul claro U+WX
6erde \+WV 6erde claro U+WV
2&an \+W_ 2&an claro U+W_
Lo!o \+WU Lo!o claro U+WU
,$rpura \+WY ,$rpura claro U+WY
.arrn \+WW 0marillo U+WW
<ris claro \+W] =lanco U+W]
8ambin podemos poner color de fondo, usando GG para fondo a(ul, GD para fondo ro!o, etc, como "emos le
sumamos D( = al color.
Color C8digo
>egro \+X\
0(ul \+XX
6erde \+XV
2&an \+X_
Lo!o \+XU
,$rpura \+XY
.arrn \+XW
<ris claro \+X]
,or e!emplo podemos combinar color de fondo a(ul & color de las letras blancas -
$ PSL;UD0D=EE0TTmD1 D0D=EE0LVEQmD10Du@DhODS1D$ U
@tros cdigos que disponibles inclu&en subra&ado, parpadeante, in"erso & oculto.
#ipo C8digo
%ubra&ado X
,arpadeante Y
;n"erso ]
@culto `
$ PSL;UD0D=EE0TTmD1 D0D=EE0LVEQmD1 D0D=EE0TmD10Du@DhODS1D$ U
!;E es el prompt secundario & por defecto "ale 0. %e usa cuando escribimos un comando inacabado, por
e!emplo -
$ echo Esto es una prueba +e escribir D
9 en +os lineas.
,or $ltimo, !;F & !;G son prompts de programacin & depuracin que "eremos mas adelante.
'ariables +e entorno internas
Existen una serie de "ariables de entorno, las cuales se resumen en la siguiente tabla, estas "ariables las fi!a
el shell no nosotros.
Nariable &escripci8n
%?ELL !ath del fichero que estamos usando.
L;>E% L#neas del terminal en caracteres.
2@LU.>% 2olumnas del terminal en caracteres.
?@.E /irectorio home del usuario.
,^/ /irectorio actual.
@L/,^/ 0nterior directorio actual.
U%EL >ombre de usuario en la cuenta donde estamos logados.
0lgunas "ariables se actuali(an dinmicamente, por e!emplo CINE; & COCOIN; en todo momento
almacenan en n$mero de filas & columnas de la terminal, & las usan algunos programas como el editor %i<%im
o emacs para modificar su apariencia.
Exportar <ariables
Las "ariables de entorno que definimos dentro de una sesin de >ash no estn disponibles para los
subprocesos que lan(a >ash 'sol las puede usar >ash & nuestro comandos interacti"os & scripts* a no ser
que las exportemos con el comando export.
$ ED!K(;<i
$ export ED!K(
@ directamente podemos exportarlo -
$ export ED!K(;<i
,odemos obtener un listado de las "ariables exportadas usando el comando en% o el comando export sin
argumentos. ,ara obtener las "ariables tanto exportadas como no exportadas debemos usar el comando set
sin argumentos.
Programacin bWsica +el shell
Un script es un fichero que contiene comandos =ash e!ecutables. Una "e( que creamos un script con nuestro
editor de texto fa"orito ha& dos forma de e!ecutarlo.
/arle permiso de e!ecucin tanto para el due7o, grupo & otros 'chmod =x archi%o_script@.Una
"e( puesto este permiso, podremos e!ecutarlo siempre que est en alguno de los directorios
indicados en la "ariable de entorno !"#$. Es mu& t#pico dentro de los script poner como primer
linea .<bin<bash, de esta forma se indica que el script debe ser e!ecutado con >ash, aunque
bash no sea el shell por defecto, otros scripts para otros lengua!es como aKP, Psh o perl tambin
se escriben empe(ando la primera l#nea.
2uando e!ecutamos un script con source, ste se e!ecuta dentro del proceso del shell, mientras
que si lo e!ecutamos como un fichero e!ecutable se e!ecuta en un subshell.
E!emplo -
$ <i e:emplo.sh
MN/bin/bash
?41'
echo K?
$ chmo+ ?x e:emplo.sh
0l llamarlo de la siguiente forma, lo estamos e!ecutando en un subshell.
$ ./e:emplo.sh
1'
6eremos que si queremos imprimir el "alor de " no mostrara nada -
$ echo $%
0hora lo llamaremos con el comando source o . 'punto* & "eremos que este se e!ecuta en el shell & no el
subshell como el e!emplo anterior.
$ source e:emplo.sh
1'
$ echo $%
1'
o
$ . ./e:emplo.sh
1'
$ echo $%
1'
Runciones
0 diferencia de los scripts, se e!ecutan dentro de la memoria del propio proceso de =ash, con lo que son ms
eficientes que e!ecutar aparte, pero tienen el incon"eniente de que tienen que estar siempre cargadas en la
memoria del proceso =ash para poder usarse.
Existe dos formas para definir una funcin -
El estilo del >ourne ;hell H O el estilo del C ;hell H
function nombre:funcion
N
a
comandos bash
a
O
nombre:funcion'*
N
a
comandos bash
a
O
>o existe diferencia entre ellos, para borrar una funcin podemos utili(ar el comando unset -f
nombre_funci8n* 2uando definimos una funcin se almacena como una "ariable de entorno 'con su "alor
almacenado la implementacin de la funcin*. ,ara e!ecutar la funcin escribimos el nombre de la funcin &
los parmetros necesarios.
$ <i 2uncion.sh
MN/bin/bash
imprimir_"alor()
?4&'
echo K?
!
$ chmo+ ?x 2uncion.sh
$ source 2uncion.sh
$ imprimir&<alor
&'
%i queremos borrar una funcin como explicamos anteriormente con el comando unset -f nombre_funci8n*
' unset -f imprimir_%alor
' imprimir_%alor
bash1 imprimir_"alor1 no se encontrC la orden
,ara "er todas las funciones que tenemos declaradas simplemente e!ecutamos +eclare -2, por e!emplo
creamos la siguiente funcin.
$ <i hola.sh
MN/bin/bash
imprimir_saludo()
echo OPola 1 KBI=<!G
!
$ chmo+ ?x hola.sh
$ source hola.sh
$ imprimir&salu+o
Pola 1 pablo
$ +eclare -2
Q
imprimir_saludo ()

echo RPola 1 KBI=<!R
!
Q
%i solo queremos obtener el nombre de la funcin sin el cdigo -
$ +eclare -2
Q
declare Af imprimir:saludo
Q
%i una funcin tiene el mismo nombre que un script o e!ecutable, la funcin tiene preferencia.
@rden de preferencia de los s#mbolos de =ash
0 continuacin se enumera el orden de preferencia que sigue =ash a la hora de resol"er un s#mbolo-
Orden &escripci8n
U 0lias.
V ,alabras cla"e ')e&Sords* como function0 if o for.
W Runciones.
X 2omandos internos 'cd, t:pe,etc@*
Y %cripts & programas e!ecutables, para los cuales se sigue el orden en
que se dan sus directorios en la "ariable de entorno !"#$.
%i nos interesa conocer la procedencia de un comando podemos usar el comando interno t:pe, si le damos un
comando nos indica cual es su fuente.
E!emplo -
$ t4pe ls
ls es un alias de 6ls Scolor4auto7
$ t4pe -path cat
/bin/cat
2on la opcin -path me de"uel"e en que ruta se encuentra el comando.
,odemos tambin pasarle la funcin de un script como la funcin que reali(amos anteriormente -
$ t4pe imprimir&salu+o
imprimir_"alor1 es una funciCn
imprimir_"alor ()

?4&'T
echo K?!
!
2omo "imos anteriormente los alias tiene ma&or prioridad que las funciones, si declaramos un alias con el
mismo nombre de la funcin & luego reali(amos un t&pe "eremos que nos muestra lo siguiente -
$ alias imprimir&salu+o;Ils -aI
$ t4pe imprimir&salu+o
imprimir_saludo es un alias de 6ls -a7
,ero si queremos "er todas las definiciones e!ecutamos t:pe -a -
$ t4pe -a imprimir&salu+o
imprimir_saludo es un alias de 6ls -a 7
imprimir_saludo1 es una funciCn
imprimir_saludo()
echo OPola 1 KBI=<!G
!
%i e!ecutamos imprimir_saludo como tiene ma&or prioridad el alias solo e!ecutara el ls & no la funcin.
$ imprimir&salu+o
./ ../ .bash_history ."im/ ."iminfo
%i queremos conocer el tipo de un s#mbolo con la opcin -t, es decir esto nos de"ol"er si es un alias,
Pe:Kord, function, builtin 'comando internos* o file.
E!emplo -
$ t4pe -t ls
alias
$ t4pe -t rm
file
$ t4pe -t c+
builtin
$ t4pe -t imprimir&salu+o
alias
=orramos el alias anteriormente definido con el comando unalias.
$ unalias imprimir&salu+o
$ t4pe -t imprimir&salu+o
function
'ariables +e Shell
,or con"enio las "ariables de entorno exportadas se escriben en ma&$sculas, acordemonos que <>U9Linux &
U>;b deferencia entre min$sculas & ma&$sculas.
Los parmetros posicionales
%on los en encargados de recibir los argumentos de un script & los parmetros de una funcin. %us nombres
son D, E, F, etc., con lo que para acceder a ellos utili(aremos, como normalmente, el s#mbolo ' de la siguiente
forma 'D, 'E, 'F, etc. 0dems tenemos el parmetro posicional ( que contiene el nombre del script que se
esta e!ecutando.
E!emplo -
$ <i parametros.sh
NM/bin/bash
N =sto es un ejemplo de script utili$ando parametros.
echo O=l nombre del script es 1 K'G
echo OIe pasaron los siguientes parametros 1 K1 K& K% K4G
$ chmo+ ?x parametros.sh
$ ./parametros.sh hola mun+o
=l nombre del script es 1 parametros.sh
Ie pasaron los siguientes parametros 1 hola mundo
2omo los parmetros 'F & 'G no se pasaron son nulos dan a una cadena "ac#a que no se imprime.
,odemos definir una funcin & llamarla con el comando source & pasar los parmetros necesarios
$ <i 2uncion&=L.sh
function recibir

echo O@a funcion K'G


echo O<ecibe como parametros K1 K& K% K4G
!
$ chmo+ ?x 2uncion&=L.sh
$ ./recibir
@a funcion recibir
<ecibe como parametros buenos dias :arcos
6ariables locales & globales
Los parmetros son locales al script o funcin & no se puede acceder o modificar desde otra funcin. ,or
e!emplo el siguiente script.
$ <i 2uncion&=L.sh
function recibir

echo O@a funcion K'G


echo O<ecibe como parametros K1 K& K% K4G
!
E!emplo de "ariable global.
$ <i 2uncion&=L.sh
function recibir

nombre475entro de la funcion7
!
nombre478ombre del programa funcion_'1.sh7
echo Knombre
recibir
echo Knombre
$ chmo+ ?x 2uncion&=L.sh
$ ./2uncion&=L.sh
8ombre del programa funcion_'1.sh
5entro de la funcion
%i queremos que una "ariable sea local debemos poner el modificador local, el cual slo se puede usar dentro
de las funciones 'no en los scripts*. 6eremos en el e!emplo que se crea una "ariable local nombre & no
modifica a la global del script.
$ <i 2uncion&=L.sh
function recibir

local nombre475entro de la funcion7


!
nombre478ombre del programa funcion_'1.sh7
echo Knombre
recibir
echo Knombre
$ chmo+ ?x 2uncion&=L.sh
$ ./2uncion&=L.sh
8ombre del programa funcion_'1.sh
8ombre del programa funcion_'1.sh
Este e!emplo combina tanto la "ariable local como global. 2omo "emos por defecto las "ariables son
globales.
$ <i 2uncion&=C.sh
function soy

local donde475entro de la funcion7


)uiensoy4:arcos
!
donde47=n el script7
echo Kdonde
soy
echo Kdonde
echo OIoy K)uiensoyG
$ chmo+ ?x 2uncion&=C.sh
$ ./2uncion&=C.sh
=n el script
=n el script
Ioy :arcos
Las "ariables H1, HC & HG
La "ariable ' contiene la cantidad de parmetros que se pasan, este "alor es de tipo cadenas de caracteres,
ms adelante "eremos como podemos con"ertir este "alor a n$mero para poder operar con el.
8anto H1 como HC nos de"uel"en los parmetros pasados al script o funcin.
E!emplo -
$ <i parametros&=L.sh
echo O8ombre del script 1 K' recibe 1 KN parametros 1 O KE
echo O8ombre del script 1 K' recibe 1 KN parametros 1 O KL
$ chmo+ ?x parametros&=L.sh
$ ./parametros&=L.sh L C E T F
8ombre del script 1 ./parametros_'1sh recibe 1 , parametros 1 1 & % 4 5 ,
8ombre del script 1 ./parametros_'1sh recibe 1 , parametros 1 1 & % 4 5 ,
La diferencia que existe entre '+ & '@ -
,odemos cambiar el s#mbolo que usa '+ para separar los argumentos indicndolo en la
"ariable de entorno IF; ';nternal Rield %eparator*, mientras que '@ siempre usa como
separador un espacio.
E!emplo-
$ <i parametros&=L.sh
UVI4707
echo O8ombre del script 1 K' recibe 1 KN parametros 1 O KE
echo O8ombre del script 1 K' recibe 1 KN parametros 1 O KL
$ ./parametros&=L.sh L C E T F
8ombre del script 1 ./parametros_'1sh recibe 1 , parametros 1 10&0%04050,
8ombre del script 1 ./parametros_'1sh recibe 1 , parametros 1 1 & % 4 5 ,
Expansin de "ariables usando lla"es
Lealmente la forma que usamos para expandir una "ariable '%ariable es una simplificacin de la forma ms
general '5%ariable6. La simplificacin se puede usar siempre que no existan ambigcedades. La forma '
5%ariable6 se usa siempre que la "ariable "a&a seguida por una letra, d#gito o guin ba!o '&*, en caso
contrario podemos usar la forma simplificada '%ariable.
E!emplo -
$ nombre;Harcos
$ apelli+o;(usso
$ echo $nombre&$apell+io
<usso
%e produce esto porque 'nombre_ piensa que es una "ariable hasta el otro s#mbolo '.
$ nombre;Harcos
$ apelli+o;(usso
$ echo $6nombre8&$6apell+io8
:arcos_<usso
8ambin lo tenemos que usar las lla"es cuando "amos a sacar el dcimo parmetro posicional. Es decir si
usamos 'D(, bash lo expandir por 'D seguido de un (, entonces la forma de usarlo para que lo interprete
como el dcimo parmetro es usando '5D(6.
pera+ores +e ca+ena
>os permiten manipular cadenas sin necesidad de escribir complicadas rutinas de procesamiento de texto.
Los operadores de cadenas nos permiten reali(ar las siguientes operaciones -
0segurarnos de una "ariable existe 'que est definida & que no es nula*.
0signar "alores por defecto a las "ariables.
8ratar errores debidos a que una "ariable no tiene un "alor asignado.
8omar o eliminar partes de la cadena que cumplen un patrn.
@peradores de sustitucin
Operador &escripci8n
HN"ariable-A"alorO %i %ariable existe & no es nula retorna el "alor de %ariable, sino retorna "alor.
HN"ariable-B"alorO %i %ariable existe & no es nula retorna %alor, sino retorna una cadena nula.
HN"ariable-d"alorO %i %ariable existe & no es nula retorna el "alor de %ariable, sino asigna %alor
a %ariable & retorno su "alor.
HN"ariable-?mensa!eO %i %ariable existe & no es nula retorna el "alor de %ariable, sino imprime
"ariable1mensaje & aborta el script que se est e!ecutando 'slo en shells no
interacti"os*. %i omitimos mensaQe imprime el mensa!e por defecto
parameter null or not set.
HN"ariable-offset-longitudO Letorna una subcadena de %ariable que empie(a en offset & tiene longitud
caracteres. El primer carcter de %ariable empie(a en la posicin (. %i se
omite longitud la subcadena empie(a en offset & continua hasta el final de
%ariable.
Los dos puntos 'O* en este operador son opcionales. %i se omiten en "e( de comprobar si existe : no es nuloR
s8lo comprueba Sue exista 'aunque sea nulo*.
E!emplo -
'5%ariableH-%alor6 se utili(a para retornar un "alor por defecto cuando el "alor de la "ariable %ariable est
indefinido. Esto no modifica el contenido de %ariable.
$ echo $6<ariableO-L=8
1'
'5%ariableH=%alor6 por contra se utili(a para comprobar que una "ariable tenga asignado un "alor no nulo.
$ echo $6<ariableO?L8
%i %ariable contiene datos entonces mostrara el "alor D esto se puede tomar como un "alor "erdadero. Esto
no modifica el contenido de %ariable.
'5%ariableHM%alor6 que asigna un "alor a la "ariable si sta est indefinida. En el siguiente e!emplo asigna el
"alor D a %ariable sino tiene "alor.
$ echo $6<ariableO;L8
1
'5%ariableHoffsetHlongitud6 podemos tomar una parte de la cadena.
$ <ariable;IHarcos PabloI
$ echo $6<ariableO=OX8
:arcos
$ echo $6<ariableOQOF8
Hablo
@peradores de b$squeda de patrones
Un uso frecuente de los operadores de b$squeda de patrones es eliminar partes de la ruta de un fichero, como
pueda ser el directorio o el nombre del fichero.
Un uso frecuente de los operadores de b$squeda de patrones es eliminar partes de la ruta un fichero, como
pueda ser el directorio o el nombre del fichero.
E!emplo -
$ ruta;/usr/share/+oc/apt/examples/sources.list
%i e!ecutamos la siguiente de operadores de b$squeda de patrones, obtendremos los siguientes resultados-
Operador Resultado
HNrutaGG919O sources.list
HNrutaG919O share9doc9apt9examples9sources.list
HNrutae.1O 9usr9share9doc9apt9examples9sources
HNrutaee.1O 9usr9share9doc9apt9examples9sources
En la b$squeda de patrones se pueden usar tanto los comodines tradicionales, el siguiente cuadro son los
comodines extendidos-
Operador &escripci8n
HN"ariableGpatronO %i patron coincide con la primera parte del "alor de %ariable, borra la parte
ms peque7a que coincide & retorna el resto.
HN"ariableGGpatronO %i patron coincide con la primera parte del "alor de %ariable, borra la parte
ms grande que coincide & retorna el resto.
HN"ariableepatronO %i patron coincide con el final del "alor de %ariable, borra la parte ms
peque7a que coincide & retorna el resto.
HN"ariable9patron9cadenaO La parte ms grande de patron que coincide en %ariable es reempla(ada por
cadena. La primera forma slo reempla(a la primera ocurrencia, & la segunda
forma reempla(a todas las ocurrencias. %i patron empie(a por debe
producirse la coincidencia al principio de %ariable, & si empie(a por T debe
producirse la coincidencia al final de %ariable. %i cadena es nula se borran
las ocurrencias. En ning$n caso %ariable se modifica, slo se retorna su
"alor con modificaciones.
E!emplo -
$ ruta;/usr/share/+oc/apt/examples/sources.list
$ echo $6rutaN/usr/-/+oc8
/apt/e(amples/sources.list
$ echo $6rutaY-.list8
/usr/share/doc/apt/e(amples/sources
$ echo $6rutaYY/examples/sources.list/8
/usr/share/doc/apt
$ echo $6ruta/usr/<ar8
/%ar/share/doc/apt/e(amples/sources
Un operador mu& interesante es 3 que es una condicin si no existe tal cosa entonces hacer esto.
E!emplo -
$ <i entra+a.sh
NM/bin/bash
fichero_entrada4K11W7Valta parametros7!
$ ./entra+a.sh
.9entrada.sh- l#nea U- U- Ralta parametros
%i queremos ir mostrando linea por linea el !"#$ tomando como separador los 'H*, reali(amos lo siguiente -
$ echo -e $6P%KH//O/JDnJ8
/usr/local/bin
/usr/bin
/bin
/usr/local/games
/usr/games
El B9nB significa salto de linea, es decir reempla(a los H por B9nB 'salto de linea*.
@peradores longitud
8iene la forma '5%ariable6 donde %ariable es la "ariable cu&o "alor queremos medir.
E!emplo -
nombre;JHarcos Pablo (ussoJ
$ echo $6Nnombre8
1*
Sustitucin +e coman+os
>os permite usar la salida de un comando como si fuera el "alor de una "ariable. La sintaxis es la siguiente -
$(coman+o)
Las comilla UcomandoU sir"e para reali(ar la e!ecucin de un comando. 0unque en =ash mantiene esta
sintaxis por compatibilidad hac#a atrs, la forma recomendada es mediante el uso de parntesis, que permite
anidar sustituciones de comandos.
E!emplo -
$ mi+ir;$(ls $HHE)
$ echo $mi+ir
8ambin podemos cargar el contenido de un archi"o a una "ariable usando '?/nombre_del_fichero@.
$ miarchi<o;$(P/etc/passS+)
$ echo $miarchi<o
=ash dispone de los comandos internos pushd & popd que nos permiten mo"ernos por los directorios de la
siguiente forma-
0l e!ecutar pushd directorio nos mo"emos a ese directorio 'como un cd* & el directorio
anterior se guarda en una pila de forma que al hacer popd regresamos al directorio que est
en la cima de la pila.
El comando dirs nos permite "er la pila de directorios que tenemos en cada momento. En
parte estos comandos son parecidos al cd -, que nos lle"a al anterior directorio en el que
estamos 'al guardado en la "ariable de entorno OC&!V&*, slo que pushd & popd nos
permite almacenar cualquier n$mero de directorios en la pila.
E!emplo -
$ push+ /usr/share/+oc
/usr/share/doc J
$ push+ /etc
/etc /usr/share/doc J
$ push+ /usr/inclu+e
/usr/include /etc /usr/share/doc J
$ +irs -<
' /usr/include
1 /etc
& /usr/share/doc
% J
' popd
/etc /usr/share/doc J
' popd
/usr/share/doc J
' popd
J
*ontrol +e 2lu:o
Las sentencias de control de flu!o es un denominador com$n de la ma&or#a de los lengua!es de
programacin, incluido =ash.
En este caso "eremos las sentencias de control de flu!o 'if, else, for, Khile, until, case & select*.
Las sentencias condicionales
La sentencia condicional tiene el siguiente formato -
if condicion
then
sentencias
elif condicion
then
sentencias
else
sentencias
fi
Este lengua!e nos obliga a que las sentencias estn organi(adas con estos retornos de carro, aunque algunas
personas prefieren poner los then en la misma l#nea que los if, para lo cual debemos de usar el separador de
comandos, que en =ash es el punto & coma 'W* as# -
if condicion T then
sentencias
elif condicion T then
sentencias
else
sentencias
fi
Los cdigos de terminacin
En U)!" los comandos terminan de"ol"iendo un cdigo numrico al que se llama c8digo de terminaci8n
'exit status* que indica si el comando tu"o xito o no.
0unque no es obligatorio que sea as#, normalmente un cdigo de terminacin ( significa que el comando
termin correctamente, & un cdigo entre D & EXX corresponde a posibles cdigos de error.
La sentencia if comprueba el cdigo de terminacin de un comando en la condicin, si ste es ( la condicin
se e"al$a como cierta.
E!emplo -
' %i ir*sh
NM/bin/bash
if cd K11WRValtan parametrosR!T then
echo K1
else
echo R5irectorio K1 no "alidoR
fi
' chmod =x ir*sh
' *<ir*sh
./ir.sh1 lXnea %1 11 Valtan parametros
' *<ir*sh xx
./ir.sh1 lXnea %1 cd1 ((1 8o e(iste el fichero o el directorio
5irectorio (( no "alido
' *<ir*sh <usr<share<doc
/usr/share/doc
Las sentencias return & exit
Los comandos U>;b retornan un cdigo de terminacin indicando el resultado de una operacin, pero qu si
estamos haciendo una funcin. 2mo retornamos el cdigo de terminacin ?.
,odemos usar la "ariable especial 3, cu&o "alor es '3, & que indica el cdigo de terminacin del $ltimo
comando e!ecutado por el shell.
E!emplo -
' cd xx
bash1 cd1 ((1 8o e(iste el fichero o el directorio
' echo '3
1
' cd <usr<share<doc
' echo '3
'
%i estamos en una funcin nosotros necesitamos de"ol"er dicho "alor mediante return para poder salir de la
funcin, esta sentencia solo puede ser usado dentro de las funciones. ,or contra, la sentencia exit puede ser
e!ecutada en cualquier sitio, & lo que hace es abandonar el script 'aunque se e!ecute dentro de una funcin*,
suele usarse para detectar situaciones errneas que hacen que el programa deba detenerse, aunque a "eces se
utili(a para QcerrarZ un programa.
E!emplo -
' %i cd*sh
cd()

builtin cd RKLR
local ct4KW
echo RK9@5HY5 -F KHY5R
return Kcd
!
2omo di!imos anteriormente las funciones tiene preferencia sobre los comando internos, como es en este
caso la funcin que declaramos anteriormente cd?@ tiene ma&or prioridad que el comando interno cd.
,ara e!ecutar el comando interno & no la funcin podemos usar el comando interno builtin, sino quedar#a en
un bucle infinito llamndose a si mismo.
builtin cd RKLR
@bser"amos tambin que tenemos que guardar el resultado de"uelto de la anterior linea en una "ariable & al
final retornamos el "alor, si no hacemos as# & retornamos sin guardarla en una "ariable, estar#amos
de"ol"iendo el "alor de"uelto por el echo A'OC&!V& -0 '!V&Y.
local ct4KW
@peradores lgicos & cdigos de terminacin
,odemos combinar "arios cdigos de terminacin de comandos mediante los operadores lgicos and
'representado con 22* or 'representado con 11* & not 'representado con .*.
E!emplo -
if cd /tmp ZZ cp archi"o.tmp KP9:=T then
Q
fi
,rimero e!ecuta el comando cd <tmp si este tiene xito 'es decir el cdigo de retorno es ( "erdadero*, e!ecuta
el siguiente comando cp archi%o*tmp '$OIE, pero si el primer comando falla no "erificara el segundo
comando, para que se cumpla la condicin ambos comandos deber#an de tener xito 'si un operando falla &a
no tiene sentido e"aluar el otro*.
.uchas "eces se utili(a el operador 22 para implementar un if. ,ara ello se apro"echa el hecho de que si el
primer operando no se cumple, no se e"al$a el segundo. %i por e!emplo queremos que se imprima el mensa!e
ANo Suedan elementosY cuando elemento sea ( podemos reali(ar el siguiente e!emplo-
2 Kelemento 4 ' 3 ZZ echo O8o )uedan elementoG
El operador 11 'or* por contra e!ecuta el primer comando, & slo si ste falla se e!ecuta el segundo.
E!emplo -
if cp archi"o_1.tmp KP9:= [[ cp archi"o_&.tmp KP9:=T then
Q
fi
En este e!emplo "emos que si se cumple una condicin no comprueba el resto.
,or $ltimo "eremos el operador . 'not*, que niega un cdigo de terminacin.
E!emplo -
if M cp archi"o_1.tmp KP9:=T then
Hrocesa el error
fi
8est condicionales
La sentencia if lo $nico que sabe es e"aluar cdigos de terminacin. ,ero no podemos "erificar si un
comando se ha e!ecutado bien.
El comando interno test nos permite comprobar otras condiciones, que le pasamos como argumento, para
acabar de"ol"iendo un cdigo de terminacin. Una forma alternati"a al comando test es el operador , -
dentro del cual metemos la condicin a e"aluar, es decir, test cadenaD M cadenaE es equi"alente a , cadenaD
M cadenaE -. Los espacios entre corchetes & los operados, o entre los operandos & el operador de
comparacin M son obligatorios. 2on lo que es coherente con la sintaxis de if que hemos "isto en el apartado
anterior.
Usando los test condicionales podemos e"aluar atributos de un fichero 'si existe, que tipo de fichero es, que
permisos tiene, etc*, comparar dos ficheros para "er cual de ellos es ms reciente, comparar cadenas, e
incluso comparar los n$meros que almacenan las cadenas 'comparacin numrica*.
2omparacin de cadenas
Operador Nerdadero si ***
strU d strV Las cadenas son iguales.
strU 5d strV Las cadenas son distintas.
strU K strV strD es menor lexicogrficamente a strE.
strU M strV strD es ma&or lexicogrficamente a strE.
An strU strD es no nula & tiene longitud ma&or a cero.
A( strU strD es nula 'tiene longitud cero*.
E!emplo -
' %i cadenas*sh
G59bin9bash
if 2 -$ K1 3T then
echo R\adena nula.R
e(it 1
fi
if 2 -$ K& 3T then
echo R\adena nula.R
e(it 1
fi
if 22 K1 4 K& 33T then
echo RIon iguales las cadenas.R
elif 22 K1 F K& 33T then
echo R@a primer cadena es mas grande )ue la segunda cadena.R
else
echo R@a segunda cadena es mas grande )ue la primer cadena.R
fi
' chmod =x cadenas*sh
' *<cadenas*sh
\adena nula.
' *<cadenas*sh a a
Ion iguales las cadenas.
' *<cadenas*sh a b
@a segunda cadena es mas grande )ue la primer cadena.
' *<cadenas*sh b a
@a primer cadena es mas grande )ue la segunda cadena.
2omparacin numrica de enteros
8ambin permite comparar "ariables que almacenan cadenas interpretando estas cadenas como n$meros,
para ello se deben de utili(ar los siguiente operadores que se muestran en la siguiente tabla -
Operador &escripci8n
Alt .enor que.
Ale .enor o igual que.
Aeq ;gual.
Age .a&or o igual que.
Agt .a&or que.
Ane >o son iguales.
Los test de condicin 'las que "an entre corchetes , -* tambin se pueden combinar usando los operadores
lgicos 22, 11 & ..
if 2 condicion 3 ZZ 2 condicion 3T then
8ambin es posible combinar comandos del shell con test de condicin-
if comando ZZ 2 condicion 3T then
0dems a ni"el de test de condicin 'dentro de los , -* tambin se pueden usar operadores lgicos, pero en
este caso debemos de usar los operadores -a 'para and* & -o 'para or*.
E!emplo -
' %i comparacion_%alores*sh
NM/bin/bash
"alor_producto_14K1
"alor_producto_&4K&
if 2 K"alor_producto_1! -le K"alor_producto_&! -a K"alor_producto_1! -le 1' 3
then
echo R=l producto ingresado es menor o igual al producto& y menor o igual a 1'R
fi
' chmod =x comparacion_%alores*sh
' *<comparacion_%alores*sh D( E(
=l producto ingresado es menor o igual al producto& y menor o igual a 1'
0unque el operador lgico -a tiene menor precedencia que el operador de comparacin -le, en expresiones
comple!as con"iene usar parntesis que a&uden a entender la expresin, pero si los usamos dentro de un test
de condicin con"iene recordar dos reglas -
Los parntesis dentro de expresiones condicionales deben ir precedidos por el carcter de
escape J 'para e"itar que se interpreten como una sustitucin de comandos*.
Los parntesis, al igual que los corchetes, deben de estar separados por un espacio.
El e!emplo anterior se puede tambin escribir de la siguiente manera -
if 2 ]( K"alor_producto_1! -le K"alor_producto_&! ]) -a ]( K"alor_producto_1! -le 1' ]) 3
then
echo R=l producto ingresado es menor o igual al producto& y menor o igual a 1'R
fi
2omprobar atributos de ficheros
El tercer tipo de operadores de comparacin nos permiten comparar atributos de fichero. Existen VV
operadores de este tipo.
Operador Nerdadero si ***
Aa archi%o archi%o existe.
Ab archi%o archi%o existe & es un dispositi"o de bloque.
Ac archi%o archi%o existe & es un dispositi"o de carcter.
Ad archi%o archi%o existe & es un directorio.
Ae archi%o archi%o existe 'equi"alente a -a*.
Af archi%o archi%o existe & en un archi"o regular.
Ag archi%o archi%o existe & tiene acti"o el bit de setgid.
A< archi%o archi%o existe & es pose#do por el grupo I& efecti%o.
Ah archi%o archi%o existe & es un enlace simblico.
A) archi%o archi%o existe & tiene el sticP: bit acti"ado.
AL archi%o archi%o existe & es un enlace simblico.
A> archi%o archi%o existe & fue modificado desde la $ltima lectura.
A@ archi%o archi%o existe & es pose#do por el user ;/ efecti"o.
Ap archi%o archi%o existe & es un pipe o named pipe.
Ar archi%o archi%o existe & podemos leerlo.
As archi%o archi%o existe & no est "ac#o.
A% archi%o archi%o existe & es un socPet.
AS archi%o archi%o existe & tenemos permiso de escritura.
Ax archi%o archi%o existe & tenemos permiso de escritura, o de b$squeda si
es un directorio.
archi%oD Ant archi%oE La fecha de modificacin de archi%oD ms moderna que '>eSer
8han* la de archi%oE.
archi%oD Aot archi%oE La fecha de modificacin de archi%oD ms antigua que '@lder
8han* la de archi%oE.
archi%oD Aef archi%oE archi%oD & archi%oE son el mismo archi"o 'Equal Rile*.
E!emplo -
' %i archi%o_(D*sh
NM/bin/bash
if 2 -$ RK1R 3
then
echo RVorma de uso 1R
echo RR
echo RK' nombre_archi"o[directorioR
echo RR
e(it 1
fi
if 2 -d RK1R 3
then
echo R=s un directorioR
fi
if 2 -@ RK1R 3
then
echo R=s un enlace simbClicoR
fi
if 2 -# RK1R 3
then
echo R^iene permiso de escrituraR
fi
if 2 -( RK1R 3
then
echo R^iene permiso de ejecucionR
fi
' chmod =x archi%o_(D*sh
' *<archi%o_(D*sh
archi"o_'1.sh nombre_archi"o[directorio
' *<archi%o_(D*sh <usr<share<doc
=s un directorio
^iene permiso de ejecucion
El bucle 2or
El bucle for en =ash es un poco distinto a los bucles de otros lengua!es como Za%a o C. 0qu# no se repite un
n$mero fi!o de "eces, sino que se procesan las palabras de na frase una a una.
La sintaxis es la siguiente -
for "ariable 2in lista3
do
Q
Ientencias )ue usan K"ariable
...
done
%i se omite in lista, se recorre el contenido de '@, pero aunque "a&amos a recorrer esta "ariable, es
con"eniente declararla expl#citamente.
E!emplo -
for planeta in :ercury >enus ^erra :arte _upiter Iaturno
do
echo Kplaneta
done
La lista del bucle for puede contener comodines. ,or e!emplo, el siguiente bucle muestra informacin
detallada de todos los archi"os que contiene un directorio actual -
for archi"os in E
do
ls -l OKarchi"osG
done
,ara recorrer los argumentos recibidos por el script, lo correcto es utili(ar Q'@Z entrecomillado, tanto '+
como '@ sin entrecomillar interpretan mal los argumentos con espacios, & Q'+Z entrecomillado considera un
slo elemento a todos los argumentos.
E!emplo -
' %i argumentos*sh
for arg in OKEG
do
echo R=lemento1 KargR
done
for arg in OKLG
do
echo R=lemento1 KargR
done
' chmod =x argumentos*sh
' *<argumentos*sh D E F G
=lemento1 1 & % 4
=lemento1 1
=lemento1 &
=lemento1 %
=lemento1 4
2omo "emos con Q'+Z los parmetros pasados los mantiene en una misma linea, mientras que con Q'@Z lo
tenemos cada parmetros en distintas lineas.
La sentencia select
>os permite generar fcilmente un men$ simple. %u sintaxis es la siguiente -
select "ariable 2in lista3
do
Ientencias )ue usan K"ariable
done
@bser"amos que tiene la misma sintaxis que el bucle for, excepto por la )e&Sord select en "e( de for. /e
hecho si omitimos in lista tambin se usa por defecto '@. Lo que genera la sentencia es un men$ con los
elementos de lista, donde asigna un n$mero. El "alor elegido se almacena en "ariable, & el n$mero elegido
en la "ariable RE!C[. Una "e( elegida una opcin por parte del usuario, se e!ecuta el cuerpo de la sentencia
& el proceso se repite en un bucle infinito.
El bucle se puede abandonar usando la sentencia breaP, se usa para abandonar un bucle, se puede usar tanto
en el caso de select, como tambin en los bucles for, Khile & until.
' %i select*sh
options14Roption1 option& )uitR
echo opciones 1 Koptions1
select opt in Koptions1 T do
echo Kopt
if 2 RKoptR4R)uitR 3T then
e(it
fi
done
' chmod =x select*sh
' *<select*sh
opciones 1 option1 option& )uit
1) option1
&) option&
%) )uit
NW
2omo "emos el prompt que nos muestra es 3 este lo podemos cambiar &a que es la "ariable !;F este mismo
lo podr#amos modificar de la siguiente manera -
' %i select*sh
!;FMBEliQa las siguientes opciones H B
options14Roption1 option& )uitR
echo opciones 1 Koptions1
select opt in Koptions1 T do
echo Kopt
if 2 RKoptR4R)uitR 3T then
e(it
fi
done
' *<select*sh
opciones 1 option1 option& )uit
1) option1
&) option&
%) )uit
EliQa las siguientes opciones H
pciones +e la l,nea +e coman+os7 expresiones aritmZticas 4 arra4s
0 lo largo de este tema aprenderemos a reali(ar dos operaciones frecuentes en la programacin de scripts- La
primera es recibir opciones 'precedidas por un guin* en la l#nea de comandos. La segunda es aprender a
reali(ar operaciones aritmticas con las "ariables, de esta forma superaremos la limitacin de que estbamos
teniendo, de que todas nuestras "ariables slo conten#an cadenas de caracteres.
@pciones de la l#nea de comandos
Es mu& t#pico que los comandos U>;b tengan el formato -
comando 2-opciones3 argumentos
Las opciones suelen preceder a los argumentos & tienen un guin delante & una abre"iatura del significado de
la opcion, mientras que se ponen dos guiones cuando indicamos la opcin completa es decir -
' ls -R
o
' ls --recursi%e
%upongamos el siguiente e!emplo donde le pasamos argumentos -
./hacer -o hola mun+o.txt
H\ HU HV HW
El problema est en que normalmente las opciones son QopcionalesZ, es decir, pueden darse o no, con lo que
el script que procesa la opcin anterior deber#a tener la forma -
if 2 K1 4 -o 3T then
=jecuta la operaciCn con K& y K%
else
=jecuta la operaciCn con K1 y K&
fi
En consecuencia, cuando el n$mero de opciones crece, la programacin de script se "uel"e engorrosa.
La sentencia shift
Esta sentencia nos permite solucionar este problema.
shift 2n3
/onde n es el n$mero de despla(amiento a la i(quierda que queremos hacer con los argumentos. %i se omite
n por defecto "ale U. En el e!emplo anterior si e!ecutamos el comando shift D, 'D pasar a ser hola*txt & 'E
pasa a ser mundo*txt, & la opcin se pierde.
if 2 K1 4 -o 3T then
Hrocesa -o
shift
fi
=jecuta la operaciCn con K1 y K&
El siguiente e!emplo muestra me!or el uso de shift, donde "eremos que recibe tres parmetros posibles .
#hile 2 -n RK(echo K1 [ grep 7`-7)R 3
do
case K1 in
-a) echo R>alor 1 -aR
TT
-b) echo R>alor 1 -bR
TT
-c) echo R>alor 1 -cR
TT
E) echo Rforma de uso 1 K' 2-a3 2-b3 2-c3 args...R
e(it 1
TT
esac
shift
done
echo R?rgumentos 1 R
La condicin del bucle busca la expresin regular B\-B significa cualquier cosa que empiece '\* por un guin
'-*, cada "e( que procesamos una opcin e!ecutamos shift para despla(ar una "e( los argumentos.
8ambin puede ser que cada parmetro tenga su propio argumento, por e!emplo que la opcin Ab recibe a
continuacin un argumento. En ese caso deber#amos modificar el bucle anterior para leer este argumento -
#hile 2 -n RK(echo K1 [ grep 7`-7)R 3
do
case K1 in
-a) echo R>alor 1 -aR
TT
-b) echo R>alor 1 -b K&R
shift
TT
-c) echo R>alor 1 -cR
TT
E) echo Rforma de uso 1 K' 2-a3 2-b argumento3 2-c3 args...R
e(it 1
TT
esac
shift
done
echo R?rgumentos 1 R
En este caso 'E es el argumento de la opcin -b & reali(amos un shift para que pase a la prxima opcin,
esto lo hace siempre & cuando pasemos como opcin -b.
El comando interno getopts
getopts nos permite procesar opciones de l#nea de comandos ms cmodamente, el problema de esto es que
solo permite una sola letra, es decir -a & no AAacti%o. 0dems getopts nos permite procesar opciones cuando
estn agrupadas 'p.e. -abc en "e( de -a -b -c* & sus argumentos de opciones cuando estos no estn separados
de la opcin por un espacio '-barg en "e( de -b argumento<s* no es con"eniente utili(arlo de esta forma
siempre con"iene tener un espacio es decir -b argumento<s. <eneralmente se usa con un bucle Khile. El
comando getopts recibe dos argumentos-
Es una cadena con las letras de las opciones que "amos a reconocer. %i la opcin tiene un
argumento se precede por dos puntos '-*. El argumento de la opcin lo podemos leer
consultando la "ariable de entorno O!#"RG. El comando getopts coge una de las opciones
de la l#nea de comandos & la almacena en una "ariable cu&o nombre se da como segundo
argumento. .ientras que el comando encuentra opciones de"uel"e el cdigo de terminacin
\, cuando no encuentra ms opciones de"uel"e el cdigo de terminacin U.
O!#"RG d son los argumentos que se pasan.
O!#IN& d es el numero del primer argumento a procesar.
#hile getopts O1ab1cG opt
do
case Kopt in
-a) echo R>alor 1 -aR
TT
-b) echo R>alor 1 -b K9H^?<aR
TT
-c) echo R>alor 1 -cR
TT
E) echo Rforma de uso 1 K' 2-a3 2-b argumento3 2-c3 args...R
e(it 1
TT
esac
done
shift K((K9H^U85 -1))
echo R?rgumentos 1 R
@bser"amos que no hace falta que ponemos shift dentro del bucle &a que getopts es lo suficientemente
inteligente como para de"ol"ernos cada "e( una opcin distinta. Lo que s# hemos hecho al final del bucle es
despla(ar tantas "eces como argumentos con opciones ha&amos encontrado. ,ara eso getopts almacena en la
"ariable de entorno O!#IN& el n$mero del primer argumento a procesar.
6ELLLLLLLLLLLLLLLL
'ariables con tipo
?asta ahora las "ariables slo pod#an contener cadenas de caracteres, despus se introdu!o la posibilidad de
asignar atributos a las "ariables que indican, por e!emplo que son enteras o de slo lectura. ,ara fi!ar los
atributos de las "ariables tenemos el comando interno declare, el cual tiene la siguiente sintaxis-
declare 2-afVir(3 2-p3 name24"alue3 Q
La siguiente tabla muestra las opciones dada por este comando, para acti"ar un atributo se precede la opcin
por un guin -, con lo que para desacti"ar un atributo decidieron preceder la opcin por un =.
Opci8n &escripci8n
Aa La "ariable es de tipo arra&.
Af .ostrar el nombre e implementacin de las funciones.
AR .ostrar slo el nombre de las funciones.
Ai La "ariable es de tipo entero.
Ar La "ariable es de slo lectura.
Ax Exporta la "ariable 'equi"alente a export*.
%i solo escribimos el comando declare sin ning$n argumento "eremos que nos muestra todas las "ariables de
entorno.
' declare
;?IP4/bin/bash
;?IP9H^I4check#insi$e1cmdhist1e(pand_aliases1e(tglob1e(t)uote1force_fignore1histappend1inter
acti"e_comments1progcomp1prompt"ars1source
path
;?IP_?@U?I=I4()
;?IP_?<a\4()
;?IP_?<a>4()
;?IP_\:5I4()
;?IP_\9:H@=^U984/etc/bash_completion
;?IP_\9:H@=^U98_\9:H?^_5U<4/etc/bash_completion.d
;?IP_\9:H@=^U98_5U<4/etc/bash_completion.d
;?IP_@U8=894()
Q
Ii usamos la opciCn -f nos muestra sClo los nombres de funciones y su implementaciCn
' declare -f
_Umage:agick ()

local cur pre"T
_get_comp_#ords_by_ref cur pre"T
case Kpre" in
-channel)
...
b si usamos la opciCn -F nos muestra sClo los nombres de las funciones e(istentes.
' declare -F
declare -f _Umage:agick
declare -f __e(pand_tilde_by_ref
declare -f __get_c#ord_at_cursor_by_ref
declare -f __git_aliased_command
declare -f __git_aliases
declare -f __git_complete_file
Q
Las "ariables que se declaran con declare dentro de una funcin son "ariables locales a la funcin, de la
misma forma que si hubisemos usado el modificador local.
,or e!emplo el siguiente script muestra como declaramos anteriormente las "ariables que en definiti"a eran
de tipo cadenas de caracteres -
' %arDMX
' %arEMG
' resultadoM'%arD+'%arE
' echo 'resultado
5E4
0hora reali(amos lo mismo pero utili(ando el comando declare Ai para indicar que las "ariables que
declaramos son de tipo entero -
' declare -i %arDMX
' declare -i %arEMG
' declare -i resultado
' resultadoM'%arD+'%arE
' echo 'resultado
&'
,ara saber que tipo es la "ariable que esta declarada con el comando declare utili(amos la opcin -p.
' declare -p resultado
declare -i resultado4R&'R
La opcin -x es equi"alente a usar el comando export sobre la "ariable, ambas son formas de exportar una
"ariable de entorno.
La opcin -r declara a la "ariable como de slo lectura, con lo que a partir de ese momento no podremos
modificar ni e!ecutar unset sobre ella.
' declare -r resultado
' resultadoM'%arD+E(
bash1 resultado1 "ariable de sClo lectura
Existe otro comando interno llamado readonl: que nos permite declarar "ariables de slo lectura, pero que
tiene ms opciones que declare -r. 2on readonl: -p nos muestra todas las "ariables de slo lectura -
' readonl: -p
declare -r
;?IP9H^I4Rcheck#insi$e1cmdhist1e(pand_aliases1e(tglob1e(t)uote1force_fignore1histappend1inte
racti"e_comments1progcomp1prompt"ars1sourcepathR
declare -ir ;?IPHU54RR
declare -r ;?IP_\9:H@=^U984R/etc/bash_completionR
declare -r ;?IP_\9:H@=^U98_\9:H?^_5U<4R/etc/bash_completion.dR
declare -r ;?IP_\9:H@=^U98_5U<4R/etc/bash_completion.dR
declare -ar ;?IP_>=<IU8V947(2'34R4R 2134R1R 2&34R5R 2%34R1R 2434RreleaseR 2534R(*,_,4-
pc-linu(-gnuR)7
declare -ir =BU54R1'''R
declare -ir HHU54R%11*R
declare -r IP=@@9H^I4Rbracee(pand1emacs1hashall1histe(pand1history1interacti"e-
comments1monitorR
declare -ir BU54R1'''R
declare -ir resultado4R&'R
0dems se nos indica si la "ariable es de tipo arra: '-a* o entero '-i*.
Usando la opcin -f podemos hacer una funcin de slo lectura 'que el usuario no pueda modificar la funcin
*. ,or e!emplo -
' readonl: -f mi_funcion
.uchas "eces se ataca un sistema modificando una funcin que se sabe que "a a e!ecutar un script en modo
superusuario 'haciendo que la funcin haga algo distinto, o algo ms de lo que hac#a originalmente*. ,ara
e"itar este ataque las funciones que "an a e!ecutarse en modo superusuario se deben de definir slo dentro
del script que las usa, aunque a "eces se necesitan llamar desde fuera & es recomendable protegerlas con la
opcin -r, &a que una "e( que una funcin se marca como de slo lectura &a no se puede quitar ese permiso.
Es decir si usamos la opcin -n para quitar este atributo, en principio el comando parece funcionar -
' readonl: -n mi_funcion
,ero si luego intentamos redefinir la funcin se producir un error indicando que la funcin sigue siendo de
slo lectura.
Expresiones aritmZticas
Las expresiones aritmticas "an encerradas entre ' ?? & @@, tambin podemos encerrarlas ente ' , & -, pero est
forma est desestimada por =ash con lo que no se recomienda usarla.
E!emplo -
' echo ]'?? FLX - '?date =TQ@ @@ dias para el FD de &iciembre]
>os permite usar los operadores relacionales 'K, M, Kd, Md, dd, 5d* & lgicos de 2 '5, II, DD* interpretando,
al igual que 2, el U como cierto & el \ como falso.
El comando interno let
>os permite asignar el resultado de una expresn aritmtica a una "ariable. 8iene la siguiente sintaxis -
let "ar4e(presion
expresion es cualquier expresin aritmtica & no necesita estar encerrada entre H''...**. La diferencia con el
comando declare -i, no crea una "ariable de tipo entero, sino una "ariable de tipo cadena de caracteres
normal.
E!emplo -
' let aMG+F
' declare -p a
declare S a4G1&G
' echo 'a
1&
Sentencias +e control +e 2lu:o aritmZticas
,ueden usarse en las distintas sentencias de control de flu!o, en cu&o caso la expresin "a entre doble
parntesis, pero sin el '.
if ((e(presiCn aritmctica))T then
cuerpo
fi
@ el Khile aritmtico tendr#a la forma -
#hile ((e(presiCn aritmctica))
do
cuerpo
done
E!emplo -
Este programa genera un n$mero aleatorio de \ a ff, & nos pregunta hasta que acertemos, o fallemos U\
"eces. %e utili(a la "ariable 'R"N&OI la cual cada "e$ )ue se lee de"uel"e un nDmero distinto.
' %i obtener*sh
let intentos41'
let solucion4K<?859:d1''
#hile ((intentos--F'))
do
read -p OUndi)ue un numero1 O numero
if ((numero44solucion))T then
echo O=(celente has ganado...G
e(it
elif ((numeroesolucion))T then
echo O=s mayorG
else
echo O=s menorG
fi
done
echo OHerdiste por superar los 1' intentos.G
' chmod =x obtener*sh
' *<obtener*sh
@bser"amos que al ser una expresin aritmtica en la condicin del if se usa MM & no M. La expresin
intentos--0( primero comprueba que intentos sea ma&or a \, & luego le aplica el operador -- que decrementa
en uno intentos.
%rra4s
=ash introdu!o los arra:s en la "ersin V.\. 0ctualmente =ash slo soporta traba!ar con arra:s
unidimensionales.
,ara declarar un arra: podemos usar como "imos anteriormente declare -a de la siguiente forma -
' declare -a "
' declare -p "
declare -a ?47()7
>o hace falta declarar un arra: con declare -a tambin podemos crearlo de la siguiente forma -
' &I";M?Cunes Iartes Iiercoles Zue%es Niernes ;abado &omingo@
' declare -p &I";
declare -a 5U?I47(2'34R@unesR 2134R:artesR 2&34R:iercolesR 2%34R_ue"esR 2434R>iernesR 253
4RIabadoR 2,34R5omingoR)7
Los elementos del arra: empie(an desde ( como "emos ,(-MYCunesY, aunque podemos cambiar los #ndices
de los elementos indicndolos expl#citamente-
' &I";M?,D-MCunes ,E-MIartes ,F-MIiercoles ,X-MZue%es ,G-MNiernes ,L-M;abado ,^-M&omingo@
' declare -p &I";
declare -a 5U?I47(2134R@unesR 2&34R:artesR 2%34R:iercolesR 2434R>iernesR 2534R_ue"esR 2,3
4RIabadoR 2-34R5omingoR)7
>o hace falta suministrar los elementos en orden, ni suministrarlos todos, los #ndices donde no colocamos un
"alor, simplemente "aldrn Qcadena nulaZ.
' COCORE;M?,X-MRoQo "_ul >lanco Negro Iarron@
' declare -p COCORE;
declare -a \9@9<=I47(2534R<ojoR 2,34R?$ulR 2-34R;lancoR 2*34R8egroR 2+34R:arronR)7
@tra forma de rellenar un arra: es la siguiente -
' CI;#"&OM?'?ls -D@@
' declare -p CI;#"&O
declare -a @UI^?5947(2'34Rarchi"o_'1.shR 2134Rarchi"o_1.tmpR 2&34Rarchi"o_&.tmpR 2%3
4Rargumentos.shR 2434Rclientes.t(tR 2534Rcond&.shR 2,34Rcond.shR 2-34Rconfig.confR 2*3
4Rdespla$a_parametros.shR 2+34Rdu-.shR 21'34Reje&.shR 21134Reje.shR 21&34Rentrada.shR 21%3
4Restado_archi"o.shR 21434Rfuncion_'1.shR 21534Rfuncion_'&.shR 21,34Rfuncion.shR 21-3
4Rget_modulos.shR 21*34Rimprimir.shR 21+34Rir.shR 2&'34Rocupa.shR 2&134Rparametros_'1.shR
2&&34Rpiladir.shR 2&%34Rselect.shR 2&434Rshift.shR 2&534Rsolucion.shR 2&,34Rtojpg.shR 2&-3
4Rtomar_archi"o.shR 2&*34R"er_cd.shR 2&+34R"er.shR 2%'34R(.shR)7
,ara acceder a los elementos usamos el operador corchete , - para indicar el #ndice del elemento a acceder, &
en este caso es obligatorio encerrar entre lla"es 5 6 la "ariable -
' echo '5CI;#"&O,X-6
cond&.sh
%i no indicamos el #ndice de elemento, por defecto nos trae el elemento de #ndice (.
' echo 'CI;#"&O
archi"o_'1.sh
0hora "eremos la forma que no ha& que hacer para indicar un elemento determinado, por esa misma ra(n
ha& que ponerlo entre lla"es -
' echo 'CI;#"&O,X-
@UI^?59253
@tra forma de declarar el arra: es introducir "alores independientemente -
' ",E-MCasa
' ",(-M"%ion
' ",D-M#ren
' declare -p "
declare -a ?47(2'34R?"ionR 2134R^renR 2&34R\asaR)7
,odemos usar los #ndices especiales + & @, los cuales retornan todos los elementos del arra: de la misma
forma que lo hacen los parmetros posicionales. 2uando no estn encerrados entre comillas dobles ambos
de"uel"en una cadena con los elementos separados por espacio, pero cuando se encierran entre comillas
dobles @ de"uel"e una cadena con los elementos separados por espacio, & + de"uel"e una cadena con los
elementos separados por el "alor de IF;.
' IF;MR
' echo '5",+-6
?"ion ^ren \asa
' echo '5",@-6
?"ion ^ren \asa
' echo A'5",@-6Y
?"ion ^ren \asa
' echo A'5",+-6Y
?"ion0^ren0\asa
8ambin podemos mostrar su contenido con un bucle for.
for datos in K?2E3!
do
echo Kdatos
done
Los elementos de un arra: a lo que no se asigna "alor tienen una cadena nula, con lo que el bucle anterior
slo imprimir#a los elementos que existan en el arra: ".
,odemos consultar la longitud de un arra: usando la forma '5arra:,@-6.
' echo '5",@-6
%
nos de"uel"e slo el n$mero de posiciones ocupadas.
/e la siguiente forma si le indicamos un #ndice nos dar la longitud del contenido del #ndice.
' echo '5",D-6
^ren
' echo '5",D-6
4
%i queremos saber que elementos no son nulos en un arra: podemos usar la forma '5.arra:,@-6, esto esta
permitido a partir de la "ersin W.\ de =ash.
' echo '5.",D-6
\ U V
%i asignamos un arra: compuesto a otro arra:, se pierden los "alores existentes, & se asignan los nue"os
"alores.
' echo '5",@-6
?"ion ^ren \asa
' "M?$ola A`ue talY "dios@
' declare -p "
declare -a ?47(2'34RPolaR 2134Rfue talR 2&34R?diosR)7
,odemos borrar un elemento del arra& -
' unset ",E-
' echo '5",@-6
declare -a ?47(2'34RPolaR 2134Rfue talR )7
@ bien podemos borrar todo el arra& -
' unset "
' declare -p "
bash1 declare1 ?1 no se encontrC
,or $ltimo "amos a comentar que algunas de las "ariables de entorno de =ash son arra:s. ,or e!emplo
>";$_NER;INFO es un arra: de slo lectura con informacin sobre la instancia actual de =ash -
' declare -p >";_NER;INFO
declare -ar ;?IP_>=<IU8V947(2'34R4R 2134R1R 2&34R5R 2%34R1R 2434RreleaseR 2534R(*,_,4-
pc-linu(-gnuR)7
@tro mu& interesante es !I!E;#"#O; es un arra: que contiene el cdigo de terminacin del ultimo
comando e!ecutado -
' ls -l
' declare -p !I!E;#"#O;
declare -a HUH=I^?^BI47(2'34R'R)7
' lsx
' declare -p !I!E;#"#O;
declare -a HUH=I^?^BI47(2'34R1&-R)7
' ls -l 1 more
' declare -p !I!E;#"#O;
declare -a HUH=I^?^BI47(2'34R'R 2134R'R)7
(e+irecciones
>osotros anteriormente &a "imos este tema los principales operadores de redireccin que son - 0, /, 00, E0 &
1, pero esta parte abarca otro grupo de comandos que muchas "eces aparecen relacionados con problemas
comple!os de redireccin.
En la siguiente tabla explicamos todos estos operadores -
Operador &escripci8n
cmdU D cmdV ,ipe+ 8oma la salida estndar de cmdD & la en"#a a la entrada estndar de cmdE.
Mfichero Ledirige la salida estndar del programa al fichero.
Kfichero Ledirige el contenido de fichero a la entrada estndar del programa.
MMfichero Ledirige la salida estndar del programa al fichero. 07ade esta a fichero si ste &a
existe.
MDfichero Ledirige la salida estndar del programa al fichero. %obrescribe a ste incluso si la
opcin noclobber est acti"ada.
KMfichero Usa a fichero tanto para la entrada estndar como para la salida estndar.
nKMfichero Usa a fichero tanto para la entrada estndar como para la salida del descriptor de
fichero n.
KKetiqueta Ruer(a a que la entrada a un comando sea la stdin hasta encontrar etiSueta. Esto se
llama here document.
KKKtexto En"#an textoa la entrada estndar del comando, es una "ariante de los here
document son los here string.
nMfichero En"#a el "alor del descriptor de fichero n al fichero.
nMMfichero En"#a el "alor del descriptor de fichero n al fichero. 07ade al final del fichero si
ste existe.
nMDfichero En"#a el "alor del descriptor de fichero n al fichero. %obrescribe a ste incluso si la
opcin noclobber est acti"ada.
nMI Enla(a la salida estndar en el descriptor de fichero n.
nKI Enla(a la entrada estndar en el descriptor de fichero n.
nMIm Enla(a el descriptor de salida m en el descriptor de fichero n.
nKIm Enla(a el descriptor de entrada m en el descriptor de fichero n.
IMfichero Ledirige la salida estndar & la salida de error estndar al fichero.
KIA 2ierra la entrada estndar.
MIA 2ierra la salida estndar.
nMIA 2ierra el descriptor de salida n.
nKIA 2ierra el descriptor de entrada n.
E!emplos -
En este e!emplo si no existe el archi"o lo crea de!ndolo en \ b&tes & si existe lo pisa de!ndolo tambin en \
b&tes.
' 0 nue%o*txt
En bash existe la opcin noclobber que por defecto no est acti"a ' & se puede acti"ar con el comando set -o
noclobber* que hace que si intentamos sobrescribir un fichero con el operador 0'redirigir a un fichero
existente* el shell produ(ca un error & no nos de!e e!ecutar esta operacin. ,odemos for(ar que se
sobrescriban los ficheros, incluso con esta opcin acti"ada, con el operador 01.
Los descriptores de fichero
?emos "isto en cap#tulos anteriores que tenemos tres descriptores principales que el ( para la entrada
estndar 'stderr*, el D para la salida estndar 'stdout*, & el E para la salida de errores estndar 'stderr*.
>os quedan los n$meros del F al ) para abrir descriptores adicionales, el descriptor X puede dar problemas &a
que cuando el shell e!ecuta un subshell el subproceso hereda este descriptor. Esto se hace as# porque a "eces
es $til asignar un n$mero de descriptor adicional a los descriptores estndar como si fueran una copia
adicional de este enlace. @tras "eces resulta $til asignar un n$mero de descriptor adicional a un fichero al
que luego nos "amos a referir por su descriptor.
El operador n0m2 enla(a el descriptor n en el descriptor de salida m.
' ls -:_ 00 resultado*log
ls1 in"alid option -- 7y7
Hruebe 6ls --help7 para mAs informaciCn.
' ls -:_ 00 resultado*log E02D
El resultado de la linea ilegal la en"#a por stdout 'D*, en "e( de stderr 'E*. %i lo hubiramos e!ecutado al re"s
es decir ls D02E lo que habr#amos hecho es en"iar el listado de directorios 'stdout* a la salida de errores
estndar 'stderr*.
El operador n/2m enla(a el descriptor n en el descriptor de entrada m.
' cat F/ cla%e*h (/2F
Enla(a el descriptor de entrada F con el fichero cla%e*h, & luego cambia stdin para que en "e( de leer de
teclado, lea del descriptor de fichero F, con lo que el contenido de cla%e*h act$a como entrada al comando
cat.
@tro e!emplo es -
' ls F0mis*ficheros D02F
0signa el descriptor de fichero de salida F al fichero mis*ficheros, & despus enla(a la salida estndar con el
descriptor F, con lo que la salida de ls "a al fichero mis*ficheros.
8ambin podemos usar el operador n/0fichero para que n sea a la "e( un descriptor de entrada & de salida
para fichero.
' cat clientes*txt
_uan
Hedro
?na
' sort F/0clientes*txt (/2F D02F
' cat clientes*txt
_uan
Hedro
?na
?na
_uan
Hedro
@bser"amos que los clientes ordenados no sobreescriben a los existentes, sino que se escriben a
continuacin. Esto se debe a que al leerlos, el puntero a fichero se ha colocado al final, & cuando despus
escribimos estamos escribiendo al final de ste.
El operador n/0fichero se puede abre"iar como /0fichero, en cu&o caso stdin se con"ierte en un descriptor
de fichero de entrada9salida con fichero como fuente & destino. Es decir, el comando anterior se podr#a haber
escrito como sort /0cleintes*txt D02(. El final del comando D02( se usa para que stdout se en"#a a stdin 'el
fichero clientes*txt*.
?a& "eces que queremos redirigir ambas salidas - gcc +*c D0errores*log E0errores*log una forma mas fcil
de abre"iar esto es gcc +*c 20errores*log.
El comando exec
Este comando nos permite cambiar las entradas & salidas de un con!unto de comandos 'de todos los que se
e!ecutan a partir de l*.
' %i exec*sh
e(ec ,eZ' N =nla$a el descriptor , a stdin.
N =sto se hace para sal"ar stdin
e(ec e data-file N <eempla$a stdin por el
N fichero data-file
read a1 N @ee la primera lXnea de data-file
read a& N@ee la segunda lXnea de data-file
echo
echo O@Xneas leidas del ficheroG
echo O------------------------------G
echo Ka1
echo Ka&
e(ec 'eZ, ,eZ- N <estaura stdin
?ere documents
El operador //etiSueta fuer(a a que la entrada a un comando sea la stdin hasta encontrar etiqueta. Este texto
que "a hasta encontrar etiqueta es lo que se llama here document.
E!emplo -
' cat 00 texto*txt //EOF
F Pola.
F =sto es un mensaje para "er como
F funciona here documents.
F=9V
Esto se puede entre otras cosas utili(ar en una conexin de un ser"idor ftp por e!emplo -
' %i conexion_ftp*sh
N Icript )ue sube un fichero a un ser"idor de V^H
N <ecibe los siguientes argumentos
N K1 Vichero a subir
N K& Ier"idor V^H
N K% 8ombre de usuario
N K4 Hass#ord
N K5 5irectorio destino
ftp ee VU8
open K1
K&
K%
cd K4
binary
put K5
)uit
VU8
Una "ariante de los here document son los here string, los cuales se lle"an a cabo el operador ///texto, &
que simplemente en"#an texto a la entrada estndar del comando.
,or e!emplo, si queremos a7adir una l#nea al principio del fichero texto*txt & guardarlo en nue%o_texto*txt
podemos usar lo siguiente -
' tituloMYIi titulo de eQemploY
' cat - texto*txt ///'titulo 0 nue%o_texto*txt
El guin '-* como argumento de cat 'al igual que en otros comandos como grep o sort* indica que ah# "a lo
que reciba por la entrada estndar 'el here string en nuestro e!emplo*. @bsr"ese que el here string 'al igual
que el here document* puede contener "ariables, en cu&o caso las expanden por su "alor antes de pasar el
here document al comando.
Entra+a 4 sali+a +e texto
En esta seccin comentaremos detalladamente los comandos echo, printf & read que nos permite reali(ar
operaciones de entrada9salida que requiere un script.
El comando interno echo
%implemente escribe en la salida estndar los argumentos que recibe.
' echo A$ola9n"diosY
Pola]n?dios
' echo -e A$ola9n"diosY
Pola
?dios
La tabla siguiente muestra las opciones que podemos utili(ar con el comando echo.
Opci8n &escripci8n
Ae 0cti"a la interpretacin de caracteres precedidos por el carcter de escape.
AE /esacti"a la interpretacin de caracteres precedidos por el carcter de escape.
Es la opcin por defecto.
An @mite el carcter Jn al final de la l#nea 'es equi"alente a la secuencia de
escape Jc*.
La siguiente tabla muestra las secuencias de escape que acepta echo 'cuando se le pasa la opcin Ae*. ,ara
que estas tengan xito deben de encerrarse entre comillas simples o dobles, &a que sino el carcter de
escape J es interpretado por el shell & no por echo.
;ecuencia de escape &escripci8n
Ja ,roduce un sonido QpoomZ 'alert*.
Jb =orra hac#a atrs 'bac)space*.
Jc @mite el Jn al final 'es equi"alente a la opcin An*. /ebe
colocarse al final de la l#nea.
Jf 2ambio de pgina de impresora 'formfeed*.
Jn 2ambio de l#nea.
Jr Letorno de carro.
Jt 8abulador.
El siguiente e!emplo repite un bucle de \ a f, con la opcin 9r lo que hace es retorna el cursor en el terminal
sin introducir un cambio de l#nea 'como lo hace el 9n*.
K for ((i4'Tie1'Tigg))
F do
F echo -n RHrocesado KiR
F sleep 1
F echo -ne R]rR
F done
El comando interno printf
2on el comando printf podemos formatear la salida por pantalla mientras que con echo no nos de!a.
' printf A$ola IundoY
Pola :undo
printf por defecto interpreta las secuencias de escape.
' printf A$ola Iundo9nY
Pola :undo
El formato de este comando es mu& parecido al de la funcin printf?@ del lengua!e C.
printf cadenaformato 2argumentos3
En la siguiente tabla describimos los formatos que podemos utili(ar los cuales empie(an por T.
Especificador &escripci8n
ec ;mprime el primer carcter de una "ariable cadena.
ed ;mprime un n$mero decimal.
ei ;gual que ed 'integer*.
ee Rormato exponencial b*precisione,=--e
eE Rormato exponencial b*precisione,=--e
ef >$mero en coma flotante b*precision
eg El que menos ocupa entre ee & ef
e< El que menos ocupa entre eE & ef
eo @ctal sin signo
es 2adena 'string*
eb ;nterpreta las secuencias de escape del argumento cadena
eq Escribe el argumento cadena de forma que pueda ser usado como entrada a
otro comando
eu >$mero sin signo 'unsigned*
ex ?exadecimal con letras en min$scula
eb ?exadecimal con letras en ma&$scu7a
ee e literal
E!emplo -
' nMF(
' nombreMIarcos
' printf AEl cliente Td es Ts9nY 'n 'nombre
=l cliente %' es :arcos
' printf A1TD(s19nY $ola
[ Pola[
%i queremos indicar un mximo para la cadena debemos de usar el campo precisi8n -
' printf A1T-D(*D(s19nY AIarcos !abloY
[:arcos Hab[
El flag a se usa para indicar que queremos alienar a la i(quierda -
' printf A1T-D(s19nY $ola
[Pola [
/os "ariantes de es son eb & eq. El especificador de formato eb hace que se interpreten las secuencias de
escape de los argumentos. Es decir -
' printf ATs9nY A$ola 9n"diosY
Pola ]n?dios
' printf ATb9nY A$ola 9n"diosY
Pola
?dios
La siguiente tabla muestra los flags de los especificadores de formato para n$meros.
Flag &escripci8n
B ,receder por B a los n$meros positi"os.
Espacio ,receder por un espacio a los n$meros positi"os.
\ Lellenar con (Ps a la i(quierda.
G ,receder por ( a los n$meros en octal To & por (x a los n$meros en
hexadecimal Tx & Tb.
E!emplo -
' printf A1T=D(d19nY XL
[ g5,[
' printf A1T(D(d19nY XL
[''''''''5,[
' printf A1Tx19nY XL
[%*[
' printf A1Tx19nY XL
['(%*[
El comando interno read
La sintaxis de este comando es -
read "ar1 "ar& Q
Esta sentencia lee una l#nea de la entrada estndar & la parte en palabras separadas por el s#mbolo que indique
la "ariable IF; 'por defecto espacio o tabulador*.
' read %arD %arE %arF
=sto es una prueba
' echo '%arD
=sto
' echo '%arE
es
' echo '%arF
una prueba
%i omitimos las "ariables, la l#nea entera se asigna a la "ariable RE!C[.
El uso de read rompe esta forma de programar, con lo que se recomienda usarlo con moderacin. 0 lo me!or
resulta ms con"eniente pedir un dato como argumento que pedir al usuario que lo introdu(ca con read.
Las principales opciones del comando read -
Opci8n &escripci8n
Aa ,ermite leer las palabras como elementos de un arra&.
Ad ,ermite indicar un delimitador de fin de l#nea.
Ae 0cti"a las teclas de edicin de readline.
An max ,ermite leer como mximo max caracteres.
Ap ,ermite indicar un texto de prompt.
At timeout ,ermite indicar un timeout para la operacin de lectura.
E!emplos -
' read -a frase
Pola mundo nue"o
' declare -p frase
declare -a frase47(2'34RPolaR 2134RmundoR 2&34Rnue"oR)7
La opcin -e es recomendable usarla en general siempre, &a que permite que se puedan usar todas las
combinaciones de teclas de readline en el prompt de read.
La opcin -n nos permite especificar un n$mero mximo de caracteres a leer. %i se intentan escribir ms
caracteres que los indicados en esta opcin simplemente se acaba la operacin de read.
La opcin -p nos permite aportar un texto de prompt al comando que se imprime antes de pedir el dato-
' read -p ACual es tu nombre H
\ual es tu nombre1 Iarcos
La opcin -t nos permite dar un tiempo mximo en segundos para el prompt, momento a partir del cual se
continua con el script. Esto es especialmente $til para los scripts de instalacin, donde a "eces el
administrador no est presente esperando a que la instalacin acabe.
' read -t D( -p ACual es tu nombre H
\ual es tu nombre1
Los blo[ues +e coman+os
En el siguiente script "eremos que estamos cambiando la entrada estndar para que read lea la entrada.
' %i idgrupo*sh
function idgrupo

UVI41
#hile read nombre asterisco U5 resto
do
if 2 K1 4 Knombre 3T then
echo R8ombre arupo 1 KnombreR
echo RU5 arupo 1 KU5R
echo R<esto 1 KrestoR
return
fi
done
!
idgrupo K1 e /etc/group
' chmod =x idgrupo*sh
' *<idgrupo*sh pablo
8ombre arupo 1 pablo
U5 arupo 1 1'''
<esto 1
,ara que esta funcin use como entrada estndar el fichero 9etc9group necesitamos redireccionar su entrada
de la siguiente forma -
' %i idgrupo*sh
function idgrupo

UVI41
#hile read nombre asterisco U5 resto
do
if 2 K1 4 Knombre 3T then
echo R8ombre arupo 1 KnombreR
echo RU5 arupo 1 KU5R
echo R<esto 1 KrestoR
return
fi
done
! / <etc<group
idgrupo K1
%i el $nico que "a a utili(ar esa entrada es el bucle Khile, podemos redirigir la entrada estndar durante la
e!ecucin del bucle Khile.
' %i idgrupo*sh
function idgrupo

UVI41
#hile read nombre asterisco U5 resto
do
if 2 K1 4 Knombre 3T then
echo R8ombre arupo 1 KnombreR
echo RU5 arupo 1 KU5R
echo R<esto 1 KrestoR
return
fi
done / <etc<group
!
idgrupo K1
8ambin por ultimo podemos redirigir la entrada de un con!unto de comandos creando un llamado bloSue de
comandos, los cuales encierran un con!unto de comandos entre lla"es.
' %i idgrupo*sh

UVI41
#hile read nombre asterisco U5 resto
do
if 2 K1 4 Knombre 3T then
echo R8ombre arupo 1 KnombreR
echo RU5 arupo 1 KU5R
echo R<esto 1 KrestoR
fi
done
! / <etc<group
En el siguiente e!emplo de un bloque de comandos que pasa a su salida a cut usando un pipe. En este caso, el
bloque de comandos tiene redirigida su entrada estndar para leer de <etc<group, & la salida del bloque de
comandos se en"#a a tra"s de un pipe a cut.
' %i idgrupo*sh

UVI41
#hile read nombre asterisco U5 resto
do
if 2 K1 4 Knombre 3T then
echo RKnombre1Kasterisco1KU51KrestoG
break
fi
done / <etc<group
! [ cut -d 717 -f %
Los coman+o coman+7 builtin 4 enable
2omo "imos en otro capitulo cuando introducimos un comando en bash el orden de preferencia en la
b$squeda del s#mbolo por parte de bash, mediante los comandos internos command, builtin & enable nos
permiten alterar este orden de preferencia.
command hace que no se busquen alias ni nombres de funciones, slo comandos internos & comandos de
fichero.
E!emplo -
cd()

command cd RKLR
local ct4KW
echo RK9@5HY5 -F KHY5R
return Kct
!
builtin es similar a command, pero es mAs restricti"o0 sClo busca comandos internos.
enable nos permite desacti"ar el nombre de un comando interno, lo cual permite que un comando de fichero
pueda e!ecutarse sin necesidad de dar toda la ruta del fichero. ,odemos usar el comando enable -a para "er
todos los comandos internos & si estn habilitados o no
El coman+o interno e<al
>os permite pasar el "alor de una "ariable al interprete de comandos para que lo e!ecute.
' e%al AlsY
?ace que el interprete de comandos e!ecute ls.
0unque en principio puede parecer un poco extra7o, el comando e%al resulta mu& potente &a que el
programa puede construir programas en tiempo de e!ecucin & luego e!ecutarlo. Estrictamente hablando no
necesitar#amos disponer del comando e%al para hacer esto con =ash, &a que siempre podemos crear un
fichero con los comandos a e!ecutar & luego e!ecutarlo usando source. ,ero e%al nos e"ita de tener que crear
un fichero.
6errrrrrrrrrrrrr
*ombnaciones +e teclas [ue en<,an se\ales
Existen "arias combinaciones de teclas que act$an sobre el proceso que se est e!ecutando en foreground en
el terminal.
2on el comando stt: podemos crear nue"as combinaciones de teclas que en"#en se7ales al proceso el
foreground usando stt: secal \letra. /onde se7al es el nombre de la secal en min$scula & sin el prefi!o ;IG.
,or e!emplo para que Ctrl=` produ(ca la se7al ;IG`OI# podemos usar -
' stt: Suit \`
*apturar se\ales +es+e un script
2omando interno trap
El comando interno trap, el cual tiene el siguiente formano -
trap cmd sig1 sig& Q
cmd es el comando que queremos e!ecutar al capturar alguna de las se7ales sigD sigE a Lgicamente cmd
puede ser una funcin o un script, & las se7ales se pueden dar por n$mero o por nombre. 8ambin se puede
e!ecutar sin argumentos, en cu&o caso nos da la lista de traps que estn fi!ados.
E!emplo -
trap Oecho 7Hulsastes \trlg\7G U8^
#hile true
do
sleep ,'T
echo O\ambio de minutoG
done
@bser"amos que al recibir la se7al ;IGIN# bash se la pasa al comando sleep, con lo que ste acaba, pero
luego se e!ecuta el trap del script, & por esta ra(n el script no acaba.
,ara pararlo ahora con Ctrl=C tenemos un problema &a que hemos cambiado la opcin por defecto, que es
#erm, por imprimir un mensa!e. ,ara terminar el script puede pararlo con Ctrl=d & luego hacerle un Pill 'que
en"#a la ;IG#ERI no la ;IGIN#*-
\ambio de minuto
`h
213g 5etenido sleep ,'
' Pill TD
' Qobs
213g ^erminado sleep ,'
8raps & funciones
2omo bien sabemos, las funciones se e!ecutan en el mismo proceso que el script que las llama, en
consecuencia dentro de una funcin se puede detectar un trap fi!ado por el script, & "ice"ersa, un trap fi!ado
por una funcin sigue acti"o cuando sta termina.
Vunction fijatrap

trap Oecho 7Hulsaste \trlg\M7G U8^


!
fijatrap
#hile true
do
sleep ,'T
echo O\ambio de minutoG
done
;gnorar se7ales
%i lo que queremos es ignorar una se7al, simplemente tenemos que pasar una cadena "ac#a 'QZ PP* en el
argumento cmd a trap.
En el prximo e!emplo "eremos que queremos ignorar la se7al ;IG$O! 'hangup*, la cual recibe un proceso
cuando su padre termina 'p.e. el shell* & produce que el proceso hi!o tambin termine.
function ignorarhup

trap OG PBH
e"al OKLG
trap S PBH
!
' ignorarhup du -h <usr0 ocupa*txt
0ctualmente existe un comando en ONIb que hace esto mismo, que es el script nohup cu&a
implementacin.
Existe un comando interno, llamado disoKn, que recibe como argumento un !ob & elimina el proceso de la
lista de !obs controlados por el shell 'con lo que no recibir#a la se7al ;IG$O! cuando el shell que lo lan(
termine*.La opcion -h 'hoo)* de este comando reali(a la misma funcin de nohup, manteniendo al proceso
en la lista de !obs, pero no en"indole la se7al ;IG$O! cuando el shell termina. 8ambin existe la opcin -a
'all* que libera a todos los procesos en bac)ground de la lista de !obs del shell.
*orutinas
Es un con!unto de dos o ms procesos e!ecutados concurrentemente por el shell, & opcionalmente con la
posibilidad de comunicarse entre ellos.
Un e!emplo de esto es cuando reali(amos ls 1 more, el shell llama a un con!unto de primiti"as, o llamadas al
sistema.
%i no se necesita que dos procesos se comuniquen ente ellos, la forma de e!ecutarlos es ms sencilla. ,or
e!emplo, si queremos lan(ar los procesos comer & beber como corutinas, podemos hacer el siguiente script-
comer Z
beber
%i beber es el $ltimo proceso en acabar, esta solucin funciona, pero si comer sigue e!ecutando despus de
que acabe de e!ecutarse el script, comer se con"ertir#a en un proceso hurfano 'tambin llamado (ombie*.
En general esto es algo indeseable, & para solucionarlo existe el comando interno Kait, el cual para al
proceso del script hasta que todos los procesos de bac)ground han acabado. Luego la forma correcta de
lan(ar las corutinas anteriores ser#a -
comer Z
beber
#ait
El comando interno Kait tambin puede recibir como argumento el ;/ o el n$mero de !ob del preoceso al que
queremos esperar.
E!emplo -
fuente4K1
shift
for destino in OKLG
do
cp Kfuente Kdestino Z
done
#ait
Esta solucin espera que todos acaben con Kait.
Subshells
@tra forma de comunicacin entre procesos, mediante subshell & el shell padre. Los subshell son parecidos
a los bloques de comandos, donde tambin podemos redirigir su entrada & salida estndar, slo que ahora se
encierran los comandos entre parntesis & el subshell,a diferencia del bloque de comandos, se e!ecuta en un
proceso aparte.
(
for ((i4'Tie4+Tigg))
do
echo Ki
done
) [ sort -r
La principal diferencia entre un subshell & un bloque de comandos es que el primero se e!ecuta en un
proceso aparte en un proceso aparte, con lo que es menos eficiente, pero a cambio no modifica "ariables del
shell actual, con lo que existe ma&or encapsulacin. ,or e!emplo, si "amos a fi!ar un trap, lo podemos fi!ar
en un subshell para no afectar al resto del script.
2uando e!ecutamos un subshell se hereda del proceso padre, es decir -
El directorio actual.
Las "ariables de entorno exportadas.
Entrada & salida estndar, como as# los errores.
>o se hereda -
Las "ariables no exportadas.
Los traps de se7ales.
La sustitucin +e procesos
Existen dos operadores de sustitucin de procesos- /?comando@ que asigna la salida estndar del comando a
un fichero 'named pipe* de slo lectura, & 0?comando@ que asigna la salida del comando a un named pipe de
slo escritura.
E!emplo -
' grep ApassKdY /?ls -l <etc<+@
Esto es equi"alente a -
' ls -l <etc<+ 1 grep ApassKdY
Lealmente la sustitucin de comandos lo que nos de"uel"e es el nombre del fichero donde se ha depositado
la salida estndar del comando -
' echo /?ls -la@
/de"/fd/,%
Depurar scripts
La tcnica ms bsica de depuracin, que seguramente &a cono(ca, es llenar el scripts de echo que muestran
como e"oluciona el programa. El ob!eti"o de este tema que pueda usar ms & me!ores tcnicas a la hora de
depurar sus scripts.
6amos a di"idirlo en dos partes, la primera "eremos como se usan ests tcnicas & en la segunda parte
"eremos paso a paso como construir un depurador de scripts con =as.
@pciones de =ash para depuracin
El shell tiene una serie de opciones para la depuracin las cuales, o bien se pasan como argumentos al lan(ar
bash, o bien se acti"an con el comando set -o opcion. %i usamos set -o opcion estamos acti"ando la opcin,
si usamos set =o opcion la estamos desacti"ando. Es decir, al re"s de lo que parece.
Opci8n de set Opci8n de bash &escripci8n
noexec An >o e!ecuta los comandos, slo comprueba su sintaxis.
"erbose A" ;mprime los comandos antes de e!ecutarlos.
xtrace Ax ;mprime los comandos a interpretar & las distintas
expansiones que se reali(an antes de e!ecutarlo.
La opcin xtrace nos muestra tanto el comando a e!ecutar, como la expansin de las sustituciones de
parmetros, de las sustituciones de comandos, & todas las dems sustituciones que se realicen.
E!emplo -
' %i lsfecha*sh
function @istaVecha

ls -lad [ grep OK1G [ cut -c54-


!
ls -lad K(@istaVecha OK1G)
' bash -x lsfecha B) "ugB
gg @istaVecha 7+ ?ug7
gg ls -lad :akefile a)uello lsfecha
gg grep 7+ ?ug7
gg cut -c54-
g ls -lad a)uello
-r#(r-(r-( 1 pablo pablo *' &+ ?ug 1,14' a)uello
2ada s#mbolo B al principio de una l#nea indica un ni"el de expansin, este s#mbolo es usado por el prompt
!;G. ,or e!emplo -
' export !;GMBxtrace-0B
' bash -x lsfecha B) "ugB
((trace-F@istaVecha 7+ ?ug7
((trace-Fls -lad :akefile a)uello lsfecha
((trace-Fgrep 7+ ?ug7
((trace-Fcut -c54-
(trace-Fls -lad a)uello
-r#(r-(r-( 1 pablo pablo *' &+ ?ug 1,14' a)uello
,odemos personali(ar aun ms el prompt poniendo "ariables en ste. ,or e!emplo, la "ariable especial
'CINENO nos permite sabe la l#nea del script que estamos e!ecutando.
' export !;GMB'(H'CINENOHB
' bash -x lsfecha B) "ugB
llsfecha11&1@istaVecha 7+ ?ug7
llsfecha1+1ls -lad :akefile a)uello lsfecha
llsfecha1+1grep 7+ ?ug7
llsfecha1+1cut -c54-
lsfecha11&1ls -lad a)uello
-r#(r-(r-( 1 pablo pablo *' &+ ?ug 1,14' a)uello
La opcin noexec sir"e para que =ash no e!ecute los comandos, slo lea los comandos & compruebe su
sintaxis. %in embargo una "e( que acti"a esta opcin con set -o noexec &a no podr "ol"er a desacti"arla, &a
que el comando set =o noexec ser parseado pero no e!ecutado por =ash.
' bash -n lsfecha B) "ugB
]a3e signals
Las faPe signals 'falsas se7ales* son un mecanismo mu& potente de a&uda a la depuracin. %e trata de
se7ales producidas por =ash, & no por un programa o suceso externo al shell.
;ecal &escripci8n
%;<Eb;8 El script acab de e!ecutarse.
%;<ELL Un comando a retornado un cdigo de terminacin distinto de \.
%;</E=U< El shell "a a e!ecutar una sentencia.
%;<LE8UL> Una funcin o script e!ecutado con source ha acabado.
La se7al %;<Eb;8
Esta se7al se acti"a !usto antes de terminar de e!ecutarse un proceso. La se7al se debe de solicitar por el
proceso 'no por el proceso padre que lan(a el proceso*, es decir, si desde el shell e!ecutamos el scrtip
miscript as#-
' trap Aecho B"cabo el scriptBY EbI#
' miscript
La se7al no se produce, sino que el trap debe de estar dentro del script.
' %i miscript
trap Oecho 7?cabo el script7G =iU^
echo O=mpie$a el scriptG
' chmod =x miscript
' *<miscript
=mpie$a el script
?cabo el script
La se7al se lan(a independientemente de como acabe el script- ,or e!ecutar la $ltima l#nea, o por encontrar
un exit.
La se7al %;<E LL
%e lan(a siempre que un comando de un script acaba con un cdigo de terminacin distinto de \. La funcin
que la captura puede hacer uso de la "ariable ? ,ara obtener su "alor.
function \apturado=<<

ct4KW
=cho O=l comando de"ol"io el codigo de terminaciCn KctG
!
trap \apturado=<< =<<
Lo que acabamos obteniendo es el n$mero de l#nea de la sentencia de la funcin CapturadoERR ERR.
function \apturado=<<

ct4KW
echo O\odigo de terminaciCn Kct en la linea K@U8=89G
!
trap P2apturadoELL HL;>E>@P ELL
8ambin existe una forma alternati"a de pedir al shell que nos informe si un comando acaba con un cdigo
de terminacin distinto de \, que es fi!ando la opcin del shell set -o errtrace, esta opcin est disponible
slo a partir de =ash W.\
La se7al %;< /E=U<
2uando se lan(a con trap, se lan(a !usto antes de e!ecutar un comando. Un problema que tiene esta se7al es
que no se hereda en las funciones que e!ecutemos desde el script, con lo que si queremos heredarla tenemos
tres opciones -
0cti"arla con trap dentro de cada funcin.
/eclarar la funcin con declare -t que hace que la funcin si herede el trap*
@ fi!ar la opcin del shell set -o functrace 'o set -F*, que hace que todas las funciones
hereden el trap de ;IG&E>OG.
La se7al %;< LE8UL>
%e lan(a cada "e( que retornamos de una funcin, o retornamos de e!ecutar un script con source. La se7al no
se lan(a cuando acabamos de e!ecutar un comando script 'a no ser que lo e!ecutemos con source*. %i
queremos hacer esto $ltimo debemos usar ;IGEbI#.
0l igual que ;IG&E>OG, la se7al ;IGRE#ORN no es heredada por las funciones. /e nue"o podemos hacer
que una funcin herede esta se7al, declarando a la funcin con declare -t, o bien acti"ando la opcin set -o
functrace.
Un +epura+or Bash
Existe un un depurador en bash llamado bashdb la forma de instalarlo es la siguiente -
' apt-get install bashdb
E!emplo -
' %i eQemplo*sh
NM/bin/bash
echo R=sto es un ejemploR
for i in 6se) 1 1'6T
do
echo Ki
done
' chmod =x eQemplo*sh
' bashdb --debugger eQemplo*sh
bash Ihell 5ebugger0 release 4.'-'.4
\opyright &''&0 &''%0 &''40 &'',0 &''-0 &''*0 &''+ <ocky ;ernstein
^his is free soft#are0 co"ered by the a8B aeneral Hublic @icense0 and you are
#elcome to change it and/or distribute copies of it under certain conditions.
(/home/pablo/menu/ejemplo.sh1%)1
%1 echo R=sto es un ejemploR
bashdbe'F list
%144Fecho R=sto es un ejemploR
41 for i in 6se) 1 1'6T
51 do
,1 echo Ki
-1 done
bashdbe1F help
?"ailable commands1
/ debug enable help ne(t sho# stepg untrace
alias delete e"al history print signal tbreak up
break disable e(amine info p#d skip trace #atch
commands display file kill )uit source tty #here
condition do#n frame list restart step unalias
continue edit handle load set step- undisplay
<eadline command line editing (emacs/"i mode) is a"ailable.
^ype RhelpR follo#ed by command name for full documentation.
Comando &escripci8n
help .uestra la a&uda & los comando que podemos utili(ar.
bt ;niciali(a.
next E!ecuta la prxima linea.
list .uestra el cdigo fuente.
x %ariable .e muestra el "alor de dicha %ariable & el tipo de "ariable*
print "ariable .e muestra el "alor de dicha %ariable.
brea) nemero de linea Leali(a un brea) en dicho n$mero de linea.
continue 2ontinua la e!ecucin hasta el brea).
quit %alir.
run 6ol"er a e!ecutar.

También podría gustarte