Bash

download Bash

of 227

description

Referencia de BASH

Transcript of Bash

  • 5/22/2018 Bash

    1/227

    El shell Bash

  • 5/22/2018 Bash

    2/227

    El shell Bash MacProgramadores

    Pg 2

    Acerca de este documento

    En este tutorial pretendemos ensear el manejo de Bash, el Bourne AgainShell de GNU. Este shell es el que proporcionan por defecto muchos sistemas

    UNIX entre ellos Mac OS X o Linux. Los ejemplos se explicarn sobre Mac OSX, pero debido a la interoperatividad que caracteriza a Bash, estos ejemplosdeberan ser exactamente igual de tiles en otros sistemas UNIX. Cuandoexistan diferencias las indicaremos para que usuarios de otros sistemaspuedan seguir correctamente este documento.

    El tutorial asume que el lector conoce los aspectos ms bsicos de qu es, ypara qu sirve un terminal. A lo largo del documento comentaremos grancantidad de comandos que estn relacionados con el shell, y que ayudan ahacer que los ejemplos resulten tiles. Sin embargo, resulta imposible abarcar

    todos los muchos y tiles comandos a los que podemos acceder desde elterminal.

    Al acabar este tutorial el lector debera de haber aprendido a personalizar suterminal para hacerlo ms manejable, a modificar o crear los scripts que con-figuran su sistema y a manipular texto mediante el uso de comandos comogrep, sed y awk.

    Nota legal

    Este tutorial ha sido escrito por Fernando Lpez Hernndez para MacProgra-madores, y de acuerdo a los derechos que le concede la legislacin espaolae internacional el autor prohbe la publicacin de este documento en cualquierotro servidor web, as como su venta, o difusin en cualquier otro medio sinautorizacin previa.

    Sin embargo el autor anima a todos los servidores web a colocar enlaces aeste documento. El autor tambin anima a bajarse o imprimirse este tutorial acualquier persona interesada en conocer el shell Bash, y las ventajas queaporta tanto al usuario como al programador.

    Madrid, Mayo 2009Para cualquier aclaracin contacte con:[email protected]

  • 5/22/2018 Bash

    3/227

    El shell Bash MacProgramadores

    Pg 3

    Tabla de contenido

    TEMA 1: Introduccin a Bash

    1. El shell que estamos usando ................................................................82. Expansin de nombres de ficheros y directorios...................................10

    2.1. Los comodines ............................................................................102.2. El comodn tilde ..........................................................................112.3. El comodn llaves ........................................................................122.4. Comodines extendidos.................................................................13

    3. Los comandos internos de Bash..........................................................154. Redirecciones y pipes ........................................................................16

    4.1. Operadores de redireccin ...........................................................164.2. Pipes ..........................................................................................175. Ejecucin secuencial y concurrente de comandos ................................18

    6. Caracteres especiales y entrecomillado ...............................................196.1. Entrecomillado ............................................................................196.2. Caracteres de escape ..................................................................206.3. Entrecomillar los entrecomillados..................................................216.4. Texto de varias lneas ..................................................................21

    TEMA 2: Combinaciones de teclas

    1.

    El historial de comandos ....................................................................24

    1.1. El comando fc............................................................................241.2. Ejecutar comandos anteriores ......................................................25

    2. Las teclas de control del terminal........................................................263. Modos de edicin en la lnea de comandos..........................................27

    3.1. Moverse por la lnea ....................................................................273.2. Borrar partes de la lnea ..............................................................283.3. Buscar en el historial ...................................................................293.4. Autocompletar con el tabulador ....................................................29

    4. La librera readline.............................................................................304.1. El fichero de configuracin ...........................................................304.2. Asignacin de teclas de sesin .....................................................32

    TEMA 3: Personalizar el entorno

    1. Los ficheros de configuracin de Bash.................................................352. Los alias ...........................................................................................363. Las opciones de Bash ........................................................................374. Las variables de entorno ....................................................................39

    4.1. Variables y entrecomillado ...........................................................394.2. Personalizar el prompt .................................................................394.3. Variables de entorno internas.......................................................424.4. Exportar variables .......................................................................42

  • 5/22/2018 Bash

    4/227

    El shell Bash MacProgramadores

    Pg 4

    TEMA 4: Programacin bsica del shell

    1. Scripts y funciones ............................................................................441.1. Scripts........................................................................................441.2. Funciones ...................................................................................441.3. Orden de preferencia de los smbolos de Bash...............................45

    2. Variables del shell..............................................................................472.1. Los parmetros posicinales.........................................................472.2. Variables locales y globales ..........................................................482.3. Las variables $*, $@y $# ............................................................502.4. Expansin de variables usando llaves............................................53

    3. Operadores de cadena.......................................................................543.1. Operadores de sustitucin............................................................543.2. Operadores de bsqueda de patrones...........................................573.3. El operador longitud ....................................................................60

    4. Sustitucin de comandos ...................................................................61TEMA 5: Control de flujo

    1. Las sentencias condicionales ..............................................................671.1. Las sentencias if, elify else ..................................................671.2. Los cdigos de terminacin ..........................................................671.3. Las sentencias returny exit ....................................................681.4. Operadores lgicos y cdigos de terminacin ................................701.5. Test condicionales .......................................................................71

    2. El bucle for .....................................................................................773. Los bucles whiley until ................................................................814. La sentencia case.............................................................................825. La sentencia select.........................................................................84TEMA 6: Opciones de lnea de comandos, expresiones aritmticas y arrays

    1. Opciones de la lnea de comandos ......................................................871.1. La sentencia shift ....................................................................871.2. El comando interno getopts ......................................................89

    2. Variables con tipo..............................................................................923. Expresiones aritmticas .....................................................................95

    3.1. Similitud con las expresiones aritmticas C ....................................953.2. El comando interno let ..............................................................963.3. Sentencias de control de flujo aritmticas .....................................983.4. Arrays ......................................................................................100

  • 5/22/2018 Bash

    5/227

    El shell Bash MacProgramadores

    Pg 5

    TEMA 7: Redirecciones

    1. Redirecciones..................................................................................1071.1. Los descriptores de fichero ........................................................ 1081.2. El comando exec...................................................................... 1101.3. Here documents........................................................................111

    2. Entrada y salida de texto ................................................................. 1132.1. El comando interno echo .......................................................... 1132.2. El comando interno printf ...................................................... 1152.3. El comando interno read .......................................................... 118

    3. Los bloques de comandos ................................................................1214. Los comandos comand, builtiny enable ....................................1245. El comando interno eval ................................................................125

    TEMA 8: Manipular texto1. Herramientas de manipulacin de texto ............................................ 129

    1.1. Edicin de stream con sed ......................................................... 1291.2. Generacin de informes con awk................................................132

    2. Expresiones regulares...................................................................... 1372.1. Caracteres y metacaracteres ...................................................... 1372.2. Los metacaracteres posicionales.................................................1392.3. Extensin de la expresin regular ...............................................1392.4. Agrupar expresiones regulares y alternativas............................... 140

    3. Programacin con sed ..................................................................... 1413.1. El pattern space y holding space ................................................1413.2. Direccionamiento ...................................................................... 1413.3. Agrupar procedimientos.............................................................1443.4. Comentarios .............................................................................1453.5. El procedimiento de sustitucin ..................................................1463.6. Procedimientos para insertar, aadir y cambiar ........................... 1493.7. Imprimir el nmero de lnea....................................................... 1503.8. Leer y escribir ficheros...............................................................1513.9. Control de flujo bsico ...............................................................1533.10. Pattern space multilnea...........................................................1543.11. Holding space .........................................................................1593.12. Control de flujo avanzado ........................................................ 163

    4. Programacin con awk.....................................................................1654.1. El bucle de proceso ................................................................... 1654.2. Variables del sistema................................................................. 1664.3. Expresiones .............................................................................. 1704.4. Formatear la salida.................................................................... 1724.5. Paso de variables como argumentos ........................................... 1734.6. Sentencias de control de flujo .................................................... 1744.7. Arrays ......................................................................................1754.8. Variables del sistema que son arrays .......................................... 1814.9. Funciones ................................................................................. 182

  • 5/22/2018 Bash

    6/227

    El shell Bash MacProgramadores

    Pg 6

    4.10. Redirecciones y pipes ..............................................................184TEMA 9: Control de procesos

    1. IDs de procesos y nmeros de jobs ..................................................1912. Control de jobs................................................................................ 192

    2.1. Foreground y background .......................................................... 1922.2. Suspender y reanudar un job ..................................................... 1932.3. El comando ps..........................................................................1942.4. El comando top........................................................................196

    3. Seales........................................................................................... 1973.1. Combinaciones de teclas que envan seales ............................... 1983.2. El comando interno kill .......................................................... 198

    4. Capturar seales desde un script ...................................................... 2004.1. El comando interno trap .......................................................... 2004.2. Traps y funciones...................................................................... 2014.3. IDs de proceso.......................................................................... 2024.4. Ignorar seales .........................................................................203

    5. Reatachar sesiones del terminal ....................................................... 2056. Corutinas........................................................................................2067. Subshells ........................................................................................2088. La sustitucin de procesos ...............................................................209TEMA 10: Depurar scripts

    1. Opciones de Bash para depuracin ...................................................2112. Fake signals ....................................................................................213

    2.1. La seal SIGEXIT..................................................................... 2132.2. La seal SIGERR....................................................................... 2142.3. La seal SIGDEBUG................................................................... 2152.4. La seal SIGRETURN................................................................. 215

    3. Un depurador Bash.......................................................................... 2163.1. Estructura del depurador ...........................................................2163.2. El driver.................................................................................... 2163.3. El prembulo ............................................................................2183.4. Funciones del depurador............................................................2193.5. Ejemplo de ejecucin.................................................................225

    Referencias

  • 5/22/2018 Bash

    7/227

    El shell Bash MacProgramadores

    Pg 7

    Tema 1Introduccin a

    Bash

    Sinopsis:

    Como se justifica en el acerca de, este tutorial va a omitir los aspectos msbsicos del shell que es normal conocer por parte de cualquier persona quehaya usado mnimamente un shell UNIX.

    En este primer tema vamos a repasar un conjunto de aspectos fundamentalesque, aunque en parte puede conocer el lector, creemos que conviene aclararantes de profundizar.

    Por consiguiente, recomendamos empezar leyendo este primer tema, ya quesino pueden quedar ciertos aspectos sin concretar que luego podran hacerfalta para seguir ms cmodamente las explicaciones.

    Debido a sus objetivos, este tema est escrito avanzando de forma conside-

    rablemente ms rpida y superficial que en resto de temas.

  • 5/22/2018 Bash

    8/227

    El shell Bash MacProgramadores

    Pg 8

    1.El shell que estamos usando

    Mac OS X trae preinstalado el shell Bash desde la versin 10.2, antes traa

    instalado el shell tcsh, pero debido a que Bash es el shell que GNU eligi parael software libre, Apple decidi dar el salto. Linux lgicamente tambin usaeste shell, con lo cual parece ser que Bash es el shell de los sistemas UNIXms utilizados, y tiene un futuro muy prometedor.

    Si queremos saber que versin de shell tenemos instalado podemos usar elcomando:

    $ echo $SHELL/bin/bash

    Este comando nos indica que shell estamos usando y en que directorio estinstalado.

    Si queremos conocer la versin de Bash podemos usar el comando:

    $ echo $BASH_VERSION2.05b.0(1)-release

    Tambin podemos saber donde est instalado Bash con el comando:

    $whereis bash/bin/bash

    Puede conocer todos los shell de que dispone su mquina con el comando:

    $ cat /etc/shells/bin/bash/bin/csh/bin/sh/bin/tcsh/bin/zsh

    Si por alguna razn no est usando Bash, pero lo tiene instalado (o lo acabade instalar) en su mquina, puede hacer que Bash sea el shell por defecto desu cuenta usando el comando:

    $ chsh -s /bin/bash

    Si prefiere usar una versin ms moderna de shell que la que vienepreinstalada con Mac OS X puede bajrsela del proyecto Fink1:

    1Si no tiene Fink instalado puede bajrselo de http://fink.sourceforge.net/

  • 5/22/2018 Bash

    9/227

    El shell Bash MacProgramadores

    Pg 9

    $ fink list bashInformation about 4975 packages read in 12 seconds.bash 3.0-2 The GNU Bourne Again Shellbash-completion 20041017-1 Command-line completions ...

    bash-doc 3.0-1 Extra documentation for ...

    $ fink install bash

    Y cambiar a este shell con:

    $ chsh -s /sw/bin/bash

    Pero antes deber introducir este shell en /etc/shells, o chshno se loaceptar como un shell vlido.

    Si ahora nos logamos de nuevo con el comando loginy preguntamos por laversin de Bash:

    $ echo $BASH/sw/bin/bash$ echo $BASH_VERSION3.00.0(1)-release

    Vemos que estamos trabajando con Bash 3.0. En este tutorial supondremosque tenemos la versin 3.0 de Bash, si alguien est usando la versin 2.05, o

    alguna anterior, puede que no le funcionen todos los ejemplos que hagamos.

  • 5/22/2018 Bash

    10/227

    El shell Bash MacProgramadores

    Pg 10

    2.Expansin de nombres de ficheros ydirectorios

    2.1. Los comodines

    Para referirnos a varios ficheros es muy tpico usar los comodines de la Tabla1.1. Un sitio tpico donde se usan los comodines es el comando ls. Estecomando sin argumentos lista todos los ficheros del directorio, pero lepodemos pasar como argumentos los nombres de los ficheros que queremoslistar:

    $ ls carta.txt leeme.txt

    Si lo que le damos son los nombres de uno o ms directorios lo que hace eslistar su contenido.

    Comodn Descripcin? Uno y slo un carcter* Cero o ms caracteres[conjunto] Uno los caracteres de conjunto[!conjunto] Un carcter que no este en conjunto

    Tabla 1.1:Comodines de fichero

    Muchas veces queremos referirnos a un conjunto de ficheros para lo cualusamos comandos de la forma:

    $ ls *.txt

    Que lista todos los ficheros acabados en .txt.

    * representa cero o ms caracteres, con lo que *edencontrara el fichero ed.

    Otro comodn menos usado es ? que sustituye por un slo carcter, porejemplo:

    $ ls carta?.txt

    Listara ficheros como carta1.txt, carta2.txt, pero no carta10.txt.

    El tercer comodn permite indicar un conjunto de caracteres que son vlidospara hacer la sustitucin, p.e. c[ao]saencontrara el fichero casay cosa,pero no cesa. Adems podemos indicar un conjunto de caracteres ASCII

    consecutivos, por ejemplo [a-z]seran todas las letras minsculas, [!0-9]

  • 5/22/2018 Bash

    11/227

    El shell Bash MacProgramadores

    Pg 11

    seran todos los caracteres ASCII excepto los dgitos, y [a-zA-Z0-9]serantodas las letras maysculas, minsculas y los dgitos.

    La razn por la que este comodn no ha sido tan usado como se esperaba esque expande por un, y slo un dgito, por ejemplo programa.[co]encontrara programa.cy programa.o, pero no programa.cpp.

    Es importante tener en cuenta que los comandos cuando se ejecutan no venlos comodines sino el resultado de la expansin. Por ejemplo si ejecutamos elcomando:

    $ cp g* /tmp

    g*se expande por todos los ficheros que cumplen el patrn, y esto es lo quese pasa al comando cp, pero si no existiera ningn fichero cuyo nombrecumpliese el patrn g*, este valor no se expande sino que se pasa tal cual alcomando, y ste ser el que fallar:

    $ cp g* /tmp/cp: g*: No such file or directory

    Es decir, como podramos pensar, al fallar no se pasa una lista vaca alcomando. Piense por un momento lo que ocurrira con algunos comandos sise hubiese diseado as.

    Este funcionamiento es ligeramente distinto al de tcsh, donde si no seexpande el comodn no se ejecuta el comando, en Bash se ejecuta elcomando aunque luego ste produzca un error.

    2.2. El comodn tilde

    El comodn tilde ~ se usa para referirse al directorio home de los usuarios(/Usersen Mac OS X o /homeen la mayora de las mquinas UNIX), porejemplo si usamos ~carol/carta.txt nos lo expande por/Users/carol/carta.txt.

    Adems podemos usar el comodn tilde para referirnos a nuestro propiodirectorio, el cuyo caso debemos de precederlo por una barra, p.e.~/carta.txt se expande por el nombre de mi directorio, en mi caso/Users/fernando/carta.txt.

    Observe la diferencia entre poner la barra y no ponerla, si no la hubierapuesto (hubiera puesto ~carta.txt), me habra expandido por la ruta

    /Users/carta.txt, y si no existe un usuario con el nombre carta.txthubiera producido un error indicando que no existe el directorio.

  • 5/22/2018 Bash

    12/227

    El shell Bash MacProgramadores

    Pg 12

    2.3. El comodn llaves

    El comodn llaves, a diferencia de los anteriores, no estudia el nombre de losficheros existentes en disco para nada, simplemente expande una palabra por

    cada una de las cadenas de caracteres que contiene, por ejemplo:$ echo c{ami,ontamina,}oncamion contaminaon con

    Es posible incluso anidarlo y genera el producto cartesiano de combinaciones:

    $ echo c{a{min,nt}a,ose}rcaminar cantar coser

    En el apartado 2.1 comentamos que un problema que tena el comodncorchete es que expanda por un y slo un carcter, lo cual era problemticosi queramos referirnos por ejemplo a todos los ficheros de un programa, yaque *.[coh]nos permite referirnos a los fichero .c, .oy .h, pero no a los.cpp.

    Usando el comodn llave podemos superar esta dificultad: *.{h,c,cpp,o}espadera en todos los ficheros con estas extensiones, aunque ahora surge unnuevo problema y es que, debido a que el comodn llave no mira que ficheroshay en disco, si no existe un fichero con alguna de las extensiones indicadas,la expansin del *no se produce, y encontraramos un mensaje de error. Porejemplo:

    $ ls *.{h,c,cpp,o}ls: *.c: No such file or directoryls: *.o: No such file or directoryclave.cpp clave.h

    Se puede usar .. para hacer algo similar a lo que hacen los corchetesobteniendo todos lo caracteres ASCII entre dos letras. Por ejemplo:

    $ echo l{a..e}la lb lc ld le

    Obsrvese que, en el caso de los corchetes, lo que obtendramos no son unconjunto de cinco palabras, sino una expansin por un fichero existente:

    $ echo cl[a-e]ve.hclave.h

    O la cadena sin expandir si no se encuentra el fichero:

    $ echo cl[e-i]ve.h

  • 5/22/2018 Bash

    13/227

    El shell Bash MacProgramadores

    Pg 13

    cl[e-i]ve.h

    Por ltimo comentar que la llave debe contener al menos dos cadenas, sinono se realiza la expansin:

    $ echo ca{a}saca{a}sa

    De nuevo este comportamiento difiere con el de tcsh, donde la expansin serealiza aunque haya una sola cadena dentro de las llaves.

    2.4. Comodines extendidos

    Bash permite usar un conjunto de comodines extendidos, pero para poder

    usarlos debemos de activar la opcin ext_globde Bash (vase el apartado3 del Tema 3) con el comando:

    $ shopt -s extglob

    En este caso se pueden usar uno de estos cinco nuevos tipos de patrones:

    ?(pattern-list)

    Cero o una ocurrencia depattern-list

    *(pattern-list)Cero o ms ocurrencias depattern-list

    +(pattern-list)Una o ms ocurrencias depattern-list

    @(pattern-list)Exactamente uno de los patrones de la lista

    !(pattern-list)

    Cualquier cosa excepto uno de los patrones de la listapattern-listrecibe uno o ms patrones separados por |. Cada patrn deesta lista puede contener comodines, por ejemplo +([0-9])busca cadenasformadas por uno o ms dgitos.

    En el apartado 2.1 vimos que un problema que presentaba el comodn ?eraque carta?.txtlistara ficheros como carta1.txt, carta2.txt, pero nocarta10.txt. Esto lo podemos solucionar con el comodn extendido+(pattern-list)de la forma: carta+([0..9]).txt

  • 5/22/2018 Bash

    14/227

    El shell Bash MacProgramadores

    Pg 14

    Tambin vimos en el apartado 2.1 que *.[cho] encontrara los ficheros conextensin .c, .oy .h, pero no haba forma de encontrar los .cppya que elcorchete slo aceptaba un carcter. Ahora podemos usar el comodn@(pattern-list) para indicar la lista de extensiones a aceptar. Porejemplo

    *.@(c|o|h|cpp)encontrara correctamente estos ficheros:

    $ ls *.@(c|o|h|cpp)clave.cpp clave.h

    Tambin hubiera sido equivalente usar @(*.c|*.o|*.h|*.cpp)ya que lospatrones pueden estar anidados.

    Si lo que hubiramos querido es encontrar todos los ficheros excepto los.gif, los .jpg y los .html podramos haber usado el patrn!(*.html|*gif|*jpg). Sin embargo, en este caso no podramos haberusado *.!(html|gif|jpg)

    Un ltimo ejemplo, si queremos borrar todos los ficheros excepto los que em-piezan por vtseguido por uno o ms dgitos podemos usar el comando:

    $ rm !(vt+([0-9]))

  • 5/22/2018 Bash

    15/227

    El shell Bash MacProgramadores

    Pg 15

    3.Los comandos internos de Bash

    Bash busca los comandos a ejecutar en los directorios indicados en la variable

    de entorno $PATH, pero adems existen una serie de comandos que nocorresponden a ficheros del disco duro, sino que son internos a Bash y estnsiempre cargados en su memoria.

    Ejemplos de estos comandos son cd, chdir, alias, seto export. Puedeobtener una lista completa de estos comandos con su descripcin ejecutando:

    $man builtin

    Y puede obtener ayuda de estos comandos usando el comando help:

    $ help aliasalias: alias [-p] [name[=value] ... ]`alias' with no arguments or with the -p option printsthe list of aliases in the form alias NAME=VALUE onstandard output.Otherwise, an alias is defined for each NAME whose VALUEis given.A trailing space in VALUE causes the next word to bechecked for alias substitution when the alias isexpanded. Alias returns true unless a NAME is given for

    which no alias has been defined.

  • 5/22/2018 Bash

    16/227

    El shell Bash MacProgramadores

    Pg 16

    4.Redirecciones y pipes

    4.1. Operadores de redireccin

    UNIX est basado en una idea muy simple pero muy til: Tratar todos lasentrada y salidas como streams (flujos) de bytes.

    Cada programa va a tener asociadas siempre una entrada estndar (pordefecto el teclado), una salida estndar (por defecto la consola), y una salidade errores estndar (por defecto tambin la consola).

    Si queremos, podemos cambiar la entrada estndar para que el programareciba datos de un fichero usando el operador de redireccin

  • 5/22/2018 Bash

    17/227

    El shell Bash MacProgramadores

    Pg 17

    $ date > ahora

    Enva el da y hora actuales al fichero ahora.

    Tambin podemos cambiar a la vez la entrada y salida estndar de unprograma usando ambos operadores de redireccin. Por ejemplo:

    $ cat < ficheroa > ficherob

    Tambin podemos cambiar la salida de errores estndar con el operador deredireccin 2>. Por ejemplo:

    $ cat < ficheroa > ficherob 2>errores

    Copia el ficheroaen el ficherob, y si se produce algn error lo escribe en

    el fichero errores.

    Si no queremos sobrescribir un fichero de salida sino aadir el contenido alfinal podemos usar el operador de redireccin >>para la salida estndar o2>>para los errores estndar. Por ejemplo:

    $ ls p* >>ficheros 2>>errores

    Aadira los ficheros que lista ls al fichero ficheros, y si se produjesenerrores los aadira al fichero errores. El operador de redireccin 2>> es

    especialmente til para almacenar los conocidos logs de errores.

    Muchas veces no se quiere que un programa muestre mensajes en la consoladel usuario, en este caso es muy comn redirigir su salida estndar y salidade errores estndar al fichero /dev/null:

    $ gcc *.cpp > /dev/null 2> /dev/null

    4.2. Pipes

    Es posible redirigir la salida estndar de un programa a la entrada estndarde otro usando el operador |(pipeline).

    morees uno de los comandos tpicos que lo usan. Este comando lo que hacees recoger la entrada estndar y irla mostrando poco a poco (pgina apgina), luego si por ejemplo tenemos un directorio con muchos ficherospodemos hacer:

    $ ls -la | more

    y se irn mostrando pgina a pgina los ficheros.

  • 5/22/2018 Bash

    18/227

    El shell Bash MacProgramadores

    Pg 18

    Segn vayamos avanzando podremos ir viendo ejemplos ms complejos, porejemplo:

    $ cut -d: -f1 < /etc/passwd | sort

    Nos muestra los nombres de todos los usuarios de la mquina ordenados al-fabticamente.

    Tngase en cuenta que el operador |separa el comando en varios comandosantes de ejecutarlo, con lo que el operador de redireccin tiene efecto slopara el comando cut.

    5.Ejecucin secuencial y concurrente de

    comandosPodemos ejecutar un comando que tarde mucho en ejecutarse y dejarloejecutando en background precedindolo por &. Por ejemplo para compilar unconjunto de ficheros fuente de un programa C++ podemos hacer:

    $ gcc *.cpp &

    Aunque el proceso se sigue ejecutando en background, los mensajes queproduce salen en la consola impidindonos trabajan cmodamente. Para

    evitarlo podemos enviar los mensajes a /dev/null:

    $ gcc *.cpp > /dev/null &

    Aunque si se produce un error, ste ir a la salida de errores estndar, con loque seguira saliendo en consola. Podramos evitarlo redirigiendo tambin lasalida de errores estndar, pero quiz sea mejor que se nos informase delerror.

    Otras veces lo que queremos es esperar a que se acabe de ejecutar un

    comando para ejecutar el siguiente, en este caso podemos usar el operador ;(punto y coma), por ejemplo, podramos querer compilar el comando clavepara luego ejecutarlo:

    $ gcc clave.cpp -o clave ; clave

    Este comando primero compila el programa, y cuando acaba de compilarlo loejecuta.

  • 5/22/2018 Bash

    19/227

    El shell Bash MacProgramadores

    Pg 19

    6.Caracteres especiales y entrecomillado

    Los caracteres , |, &*, ? , ~, [, ], {, } son ejemplos de caracteres

    especiales para Bash que ya hemos visto. La Tabla 1.2 muestra todos loscaracteres especiales de Bash.

    Ms adelante veremos otros comandos tienen sus propios caracteresespeciales, como puedan ser los comandos que usan expresiones regulares olos operadores de manejo de cadenas.

    Carcter Descripcin~ Directorio home` Sustitucin de comando

    # Comentario$ Variable& Proceso en background; Separador de comandos* Comodn 0 a n caracteres? Comodn de un slo carcter/ Separador de directorios( Empezar un subshell) Terminar un subshell\ Carcter de escape

    < Redirigir la entrada> Redirigir la salida| Pipe[ Empieza conjunto de caracteres comodn] Acaba conjunto de caracteres comodn{ Empieza un bloque de comando} Acaba un bloque de comando' Entrecomillado fuerte" Entrecomillado dbil! No lgico de cdigo de terminacin

    Tabla 1.2:Caracteres especiales de Bash

    6.1. Entrecomillado

    Aunque los caracteres especiales son muy tiles para Bash, a veces queremosusar un carcter especial literalmente, es decir sin su significado especial, eneste caso necesitamos entrecomillarlo(quoting).

    Por ejemplo si queremos escribir en consola el mensaje: 2*3>5 es unaexpresin cierta, podemos usar el comando echoas:

  • 5/22/2018 Bash

    20/227

    El shell Bash MacProgramadores

    Pg 20

    $ echo 2*3>5 es una expresion cierta

    Al ejecutarlo podemos observar que no da ninguna salida, pero realmente hacreado el fichero 5 con el texto 2*3 es una expresion cierta. La razn

    est en que >5ha sido entendido como redirigir al fichero 5, y adems se haintentado ejecutar el carcter especial *, pero al no encontrar ningn ficheroque cumpliera el patrn no se ha expandido y se ha pasado el parmetro aechotal cual.

    Sin embargo si entrecomillamos usando ', el carcter de entrecomilladofuerteobtenemos el resultado esperado:

    $ echo '2*3>5 es una expresion cierta'2*3>5 es una expresion cierta

    Un ejemplo ms prctico del entrecomillado es el comando find que nospermite buscar ficheros por muchos criterios. Por ejemplo para buscar pornombre usa el argumento -namepatron. Si por ejemplo queremos buscartodos los ficheros .cen nuestra mquina podemos intentar hacer:

    $ find / -name *.c

    Pero si tenemos la mala suerte de que en el directorio actual exista algnfichero .c, sustituir el comodn y buscar el nombre de el/los ficheros de

    nuestro directorio actual en el disco duro. Para evitarlo es recomendableentrecomillarlo:

    $ find / -name '*.c'

    En la Tabla 1.2 aparece el entrecomillado dbil ", el cual pasa slo poralgunos de los pasos del shell, o dicho con otras palabras, interpreta sloalgunos caracteres especiales. Ms adelante veremos cuando es preferibleusar este tipo de entrecomillado, de momento usaremos slo elentrecomillado fuerte.

    6.2. Caracteres de escape

    Otra forma de cambiar el significado de un carcter de escape es precederlopor \, que es lo que se llama el carcter de escape.

    Por ejemplo en el ejemplo anterior podramos haber hecho:

    $ echo 2\*3\>5 es una expresion cierta

    2*3>5 es una expresion cierta

  • 5/22/2018 Bash

    21/227

    El shell Bash MacProgramadores

    Pg 21

    Donde hemos puesto el carcter de escape a los caracteres especiales paraque Bash no los interprete.

    Tambin este carcter se usa para poder poner espacios a los nombres deficheros, ya que el espacio es interpretado por Bash como un separador deargumentos de la lnea de comandos, si queremos que no considere elespacio como un cambio de argumento podemos preceder el espacio por \.Por ejemplo el fichero Una historia.avi lo reproduzco en mi ordenadorcon mplayeras:

    $mplayer Una\ historia.avi

    Si queremos que Bash no interprete el carcter de escape podemosentrecomillarlo '\', o bien hacer que l se preceda a si mismo \\.

    6.3. Entrecomillar los entrecomillados

    Podemos usar el carcter de escape para que no se interpreten losentrecomillados simples o dobles, es decir:

    $ echo \"2\*3\>5\" es una expresion cierta"2*3>5" es una expresion cierta$ echo \'2\*3\>5\' es una expresion cierta'2*3>5' es una expresion cierta

    6.4. Texto de varias lneas

    Otro problema es como escribir un comando que ocupa varias lneas. Bashnos permite utilizar el carcter de escape para ignorar los cambios de lnea dela siguiente forma:

    $ echo En un lugar de la Mancha de cuyo nombre no \> quiero acordarme no a mucho tiempo viva un \

    > hidalgo caballero.En un lugar de la Mancha de cuyo nombre no quiero acordarno a mucho tiempo viva un hidalgo caballero.

    Al pulsar intro Bash nos devuelve el segundo prompt, que por defecto es >, ynos permite seguir escribiendo.

    Una segunda opcin es entrecomillar y no cerrar las comillas, con lo que Bashnos pide que sigamos escribiendo sin necesidad de poner un carcter deescape a los cambios de lnea:

    $ echo 'En un lugar de la Mancha de cuyo nombre no

  • 5/22/2018 Bash

    22/227

    El shell Bash MacProgramadores

    Pg 22

    > quiero acordarme no a mucho tiempo viva un> hidalgo caballero.'En un lugar de la Mancha de cuyo nombre noquiero acordar no a mucho tiempo viva unhidalgo caballero.

    La diferencia est en que en el primer caso los cambios de lnea soneliminados, y en el segundo caso no.

    Si este documento le est resultando til puede plantearse el ayudarnos amejorarlo: Anotando los errores editoriales y problemas que encuentre y envindlos

    al sistema de Bug Report de Mac Programadores. Realizando una donacin a travs de la web de Mac Programadores.

  • 5/22/2018 Bash

    23/227

    El shell Bash MacProgramadores

    Pg 23

    Tema 2Combinaciones

    de teclas

    Sinopsis:

    Nada es ms til a la hora de manejar de forma frecuente un programa quesaber manejar un buen conjunto de combinaciones de teclas que nos ayuden

    a realizar operaciones frecuentes rpidamente.

    En el caso de Bash es fcil identificar cuando un usuario conoce estas combi-naciones de teclas: Nos sorprende ver con que velocidad escribe en su conso-la.

    En este tema comentaremos las combinaciones de teclas ms tiles. Le reco-mendamos que intente recordarlas y que vuelva a consultar este tema cuan-tas veces haga falta hasta que las utilice de forma mecnica, ver como au-menta su productividad.

  • 5/22/2018 Bash

    24/227

    El shell Bash MacProgramadores

    Pg 24

    1.El historial de comandos

    Bash mantiene un histrico de comandos el cual lee al arrancar del ficherosituado en el directorio home .bash_history, durante su ejecucin va

    almacenando en memoria los comandos ejecutados, y al acabar la sesin losescribe al final del fichero .bash_history.

    En principio podemos modificar el fichero que usa Bash para guardar elhistrico indicndolo en la variable de entorno BASH_HISTORY. Aunqueraramente ser til hacer esto.

    Puede usar el comando historypara obtener un listado de su historial. Parabuscar un comando usado recientemente puede usar:

    $ history | grep "algo"

    La forma ms cmoda de referirse a comandos previamente utilizados es usarlas teclas del cursor flecha arriba y flecha abajo. Si an no las conocaprubelas.

    En los siguientes subapartados comentaremos ms a fondo como aprovecharal mximo su histrico de comandos.

    1.1. El comando fc

    El comando fc (fix command) es un clsico del C Shell trado al mundo deBash. fces un comando tan importante que es un comando interno de Bashque podemos usar para examinar los ltimos comandos, y para editar uno deellos.

    Al ser un comando interno no use man para obtener informacin sobre l,utilice el comando:

    $ help fc

    Podemos obtener un listado de los ltimos comandos usados junto con sunumero usando:

    $ fc -l

    Vemos que este comando es equivalente a history, excepto que lista slolos ltimos comandos del historial y no todos. Para editar uno de ellosindicamos su nmero a fc:

    $ fc 42

  • 5/22/2018 Bash

    25/227

    El shell Bash MacProgramadores

    Pg 25

    fc abre el comando en el editor que tengamos predefinido en la variableEDITORy nos permite editarlo.

    El principal problema de diseo que tiene este comando es que al acabar deeditar el comando (al salir del editor) lo ejecuta, comportamiento que puedeser muy peligroso dependiendo del comando que hayamos editado.

    1.2. Ejecutar comandos anteriores

    La Tabla 2.1 muestra otro conjunto de comandos internos de Bash (tambinheredados de C Shell) que permiten ejecutar comandos del histrico.

    Comando Descripcin!! Ejecutar el ltimo comando!n Ejecutar el comando nmero n!cadena Ejecutar el ltimo comando que empiece por cadena

    Tabla 2.1: Comandos internos para ejecutar comandos del histrico

    El ms til de ellos es !cadena,ya que con dar las primeras letras de uncomando que hayamos ejecutado previamente lo busca en el historial y loejecuta. Tengase en cuenta que ejecuta el comando ms reciente queempiece por cadena.

    Si hemos consultado el historial, con historyo fc -l, podemos ejecutarun comando por nmero usando !n.

  • 5/22/2018 Bash

    26/227

    El shell Bash MacProgramadores

    Pg 26

    2.Las teclas de control del terminal

    Las teclas de control del terminal son combinaciones de teclas que interpreta

    el terminal (no Bash).

    Podemos preguntar por las teclas de control del terminal usando el comando:

    $ stty allspeed 9600 baud; 24 rows; 80 columns;lflags: icanon isig iexten echo echoe -echok echoke

    -echonl echoctl -echoprt -altwerase -noflsh-tostop -flusho pendin -nokerninfo -extproc

    iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixanyimaxbel -ignbrk brkint -inpck -ignpar -parmrk

    oflags: opost onlcr -oxtabs -onocr -onlretcflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb

    -crtscts -dsrflow -dtrflow -mdmbufdiscard dsusp eof eol eol2 erase intr^O ^Y ^D ^? ^Ckill lnext min quit reprint start status^U ^V 1 ^\ ^R ^Q stop susp time werase^S ^Z 0 ^W

    El comando, aparte de darnos ciertos flags sobre distintos aspectos delcomportamiento del terminal, nos muestra las combinaciones de teclas quetenemos asignadas a las tareas ms frecuentes (recurdese que ^X significaCtrl+X). Algunas de estas combinaciones de teclas estn obsoletas, y nomerece mucho la pena recordarlas, pero otras, las que se muestran en laTabla 2.2, si que son muy tiles:

    Combinacinde tecla

    Nombrestty

    Descripcin

    Ctrl+C intr Para el comando actualCtrl+\ quit Fuerza la parada del comando actual (usar si

    Ctrl+C no responde)Ctrl+D eof Final del flujo de entradaCtrl+U kill Borra desde la posicin actual al principio de la

    lneaCtrl+W werase Borra desde la posicin actual al principio de la

    palabra

    Tabla 2.2: Teclas de control del terminal

    Para detener un comando es muy tpico usar la combinacin de teclas Ctrl+C,

    sta manda un mensaje al programa para que pueda terminar liberandocorrectamente los recursos asignados. Si este programa por alguna razn no

  • 5/22/2018 Bash

    27/227

    El shell Bash MacProgramadores

    Pg 27

    termina (ignora el mensaje que le enva Ctrl+C) siempre podemos usarCtrl+\, el cual termina el programa sin esperar a que este libere recursos, conlo que esta combinacin de teclas slo debe ser usada cuando Ctrl+C no hafuncionado.

    Otra combinacin de teclas que ya hemos visto en el apartado 4.1 es Ctrl+D,que nos permita indicar un fin de flujo, cuando el flujo proceda del teclado.

    Las otras combinaciones de teclas que vamos a estudiar en esta seccin sonlas que nos permiten borrar "hacia tras" una palabra Ctrl+W, o toda la fraseCtrl+U. Prubelas en su consola y procure recordar estas combinaciones deteclas, son muy tiles cuando se equivoca o quiere cambiar el comando queest usando.

    3.Modos de edicin en la lnea de comandos

    Por qu no puedo editar mis comandos Bash de la misma forma que editotexto en un editor de texto? Esta es una idea introducida por Bash. Enconcreto existen los modos de edicin de los dos editores ms conocidos enel mundo UNIX: vi y emacs.

    Por defecto Bash utiliza las teclas del modo de edicin de emacs, pero puedecambiar a las teclas del modo de edicin de vi usando el comando:

    $ set -o vi

    Y volver a la combinacin de teclas por defecto con:

    $ set -o emacs

    Nosotros en est seccin veremos slo las teclas de edicin de emacs que sepueden usar tambin en Bash, si no conoce emacs le recomendamos queaprenda a usarlo, porque es, y ser durante muchos aos, un clsico delmundo de UNIX. Si es usted un amante de vi slo le diremos que tiene que

    preceder las teclas rpidas por la tecla de escape, y pulsar ipara volver aescribir.

    3.1. Moverse por la lnea

    Algo que se hace muy a menudo es moverse por la lnea de edicin, puede iral principio y final de la lnea usando las combinaciones de tecla Ctrl+A (ir alprincipio) y Ctrl+E (ir al final), si lo que quiere es moverse una palabra hacaatrs o una palabra hacia adelante utilice Esc+B y Esc+F respectivamente.Tambin puede moverse una letra atrs o adelante con Ctrl+B y Ctrl+F, pero

  • 5/22/2018 Bash

    28/227

    El shell Bash MacProgramadores

    Pg 28

    desde que los teclados tienen cursores estas teclas han perdido su utilidadreal. Estas teclas se resumen en la Tabla 2.3.

    Combinacinde teclas

    Descripcin

    Ctrl+A Ir al principio de la lneaCtrl+E Ir al final de la lneaEsc+B Ir una palabra hacia atrs (backward)Esc+F Ir una palabra hacia adelante (forward)Ctrl+B Ir una letra hacia atrsCtrl+F Ir una letra hacia adelante

    Tabla 2.3: Combinaciones de teclas para moverse por la lnea

    Otra opcin muy til, pero exclusiva del terminal de Mac OS X, es pulsar en laposicin de la lnea a la que quiere moverse con la tecla Opcionpulsada.

    3.2. Borrar partes de la lnea

    Otra operacin que es muy comn es querer borrar partes de la lnea. Lascombinaciones de teclas que vamos a comentar se resumen en la Tabla 2.4.

    En el apartado 2 ya vimos que combinaciones de tecla proporcionaba elterminal, y vimos que con Ctrl+U podamos borrar desde la posicin delcursor al principio de la lnea. Si lo que queremos es borrar hasta el final de lalnea podemos usar la combinacin de tecla emacs Ctrl+K.

    Si lo que queremos es borrar slo desde a posicin actual del cursor hasta elprincipio de la palabra donde estemos situados, vimos que podamos usarCtrl+W. Si lo que queremos es borrar de la posicin del cursor actual hasta elfinal de la palabra donde estemos situados podemos usar Esc+D.

    Para borrar una sola letra es muy tpico que la tecla de borrar haca atrs !s que funcione, pero normalmente la tecla DEL no suele funcionar, y en sulugar podemos usar Ctrl+D.

    La ltima operacin de borrado se puede deshacer siempre con la teclaCtrl+Y.

    Combinacinde teclas

    Descripcin

    Ctrl+U Borra de la posicin actual al principio de la lneaCtrl+K Borra de la posicin actual al final de la lneaCtrl+W Borra de la posicin actual al principio de la palabraEsc+D Borra de la posicin actual al final de la palabraCtrl+D Borra el carcter actual hacia adelante

    Ctrl+Y Deshace el ltimo borrado (Yank)Tabla 2.4: Combinaciones de teclas para borrar

  • 5/22/2018 Bash

    29/227

    El shell Bash MacProgramadores

    Pg 29

    3.3. Buscar en el historial

    Ya comentamos que las teclas del cursor nos permitan movernos por elhistrico de comandos, pero si queremos buscar un determinado comando

    podemos usar Ctrl+R, que nos permite buscar haca atrs en el historial uncomando que contenga un determinado texto. Al pulsar esta combinacin deteclas el prompt cambia de forma, y segn vamos escribiendo nos vaindicando el comando del histrico que cumple el patrn dado:

    (reverse-i-search)`yuvs': yuvscaler -O SIZE_600x400 result2.yuv

    Si pulsamos intro se ejecutar el comando actualmente encontrado. Si porcontra pulsamos Esc pasaremos a poder editar el comando encontrado. Porltimo si pulsamos Ctrl+G se abortar la bsqueda y la lnea de edicinquedar limpia. Estas combinaciones de teclas se resumen en la Tabla 2.5.

    Combinacinde teclas

    Descripcin

    Ctrl+R Realiza una bsqueda hacia atrs (Reverse)Intro Ejecuta el comando encontradoEsc Pasa a editar el comando encontradoCtrl+G Cancela la bsqueda y deja limpia la lnea de edicin

    Tabla 2.5: Combinaciones de teclas para bsquedas

    3.4. Autocompletar con el tabulador

    Una tecla muy conocida en Bash es el tabulador que nos ayuda a terminar derellenar un comando con el nombre de un comando, de una variable, de unfichero o directorio, o con el nombre de una funcin Bash. Para ello se siguenlas siguientes regla cuando se pulsa el tabulador:

    1. Si no hay nada que empiece por el texto de la palabra que precede alcursor se produce un pitido que informa del problema.

    2. Si hay un comando (en el PATH), una variable (siempre precedida por$), un nombre de fichero o funcin Bash que comienza por el texto es-crito, Bash completa la palabra.

    3. Si hay un directorio que comienza por el nombre escrito, Bash comple-ta el nombre de directorio seguido por una barra de separacin denombres de directorios /.

  • 5/22/2018 Bash

    30/227

    El shell Bash MacProgramadores

    Pg 30

    4. Si hay ms de una forma de completar la palabra el shell completa loms que puede y emite un pitido informando de que no la pudo termi-nar de completar.

    5. Cuando Bash no puede completar una cadena (por haber varias posi-bles que empiezan igual), podemos pulsar dos veces el tabulador y senos mostrar una lista con las posibles cadenas candidatas.

    4.La librera readline

    La librera readline es una librera GNU que permite editar lneas de textousando los modos de emacs y vi. Aunque originariamente creada por Bash,actualmente la utilizan multitud de comandos GNU. Esto permite estandarizar

    las combinaciones de teclas entre muchos comandos.readline se puede personalizar usando ficheros de configuracin o bienasignando combinaciones de teclas para la sesin. En los siguientessubapartados estudiaremos cada una de estas formas de configurarla.

    4.1. El fichero de configuracin

    readline tiene un fichero de configuracin global que debe ser colocado en

    /etc/inputrc, y otro para cada usuario que por defecto se llama.inputrc y que se debe colocar en el directorio home de cada usuario.Podemos cambiar este fichero usando la variable de entorno INPUTRCparaindicar una ubicacin distinta.

    Cuando Bash arranca lee estos ficheros (si existen) y carga sus valores.Dentro del fichero puede haber comentarios (precedidos por #),combinaciones de teclas y asignaciones a variables de readline.

    4.1.1. Combinaciones de teclas

    El primer tipo de entradas que puede haber en este fichero son asignacionesde combinaciones de teclas a funciones de readline. Readline tiene unconjunto grande de funciones que podemos encontrar documentadas eninfo readline o en man bash. Estas funciones realizan multitud deoperaciones comunes. Para listar estas variables podemos crear el fichero.inputrcen nuestro directorio home y aadir la siguiente entrada:

    # Lista las funciones y variables de readline

    "\C-x\C-f": dump-functions"\C-x\C-v": dump-variables

  • 5/22/2018 Bash

    31/227

    El shell Bash MacProgramadores

    Pg 31

    Como el fichero .inputrc no se lee hasta logarnos de nuevo en Bashpodemos usar la combinacin de teclas Ctrl+X Ctrl+R para que readlinevuelva a leer este fichero.

    Ahora hemos indicado que la combinacin de teclas Ctrl+X Ctrl+F muestre lasfunciones de readline (ejecute la funcin dump-variables()de readline), yque Ctrl+X Ctrl+V muestre las variables de readline.

    Secuencia Descripcin\C- Tecla Ctrl\M- Tecla de escape (Meta)\e Secuencia de escape\\ El carcter \literal\" El carcter

    "literal

    \' El carcter 'literal

    Tabla 2.6: Secuencias usadas en el fichero de configuracin de readline

    La Tabla 2.6 muestra como representar las combinaciones de teclas: Ctrl serepresenta con \C-como hemos visto, la tecla de escape (Meta) con \M-, ypor ltimo si queremos referirnos a teclas especiales podemos usarsecuencias de escape que se representan con \e.

    Por ejemplo, vimos que para borrar una lnea de la posicin del cursor alprincipio de la lnea usbamos Ctrl-U, y para borrarlo de la posicin actual alfinal de la lnea Ctrl+K, pero desafortunadamente por defecto no hay ningunacombinacin de teclas que borre toda la lnea (adelante y atrs). Podemosinventarnos la combinacin de teclas Esc+K, que llama a la funcin kill-whole-line() de readline, modificando el fichero de configuracin dereadline como se muestra ms abajo. Otro problema que tiene el terminal esque normalmente la teclas DEL no funciona correctamente, en este casonecesitamos usar una secuencia de escape para hacer que esta tecla llame ala funcin delete-char()de readline.

    # Borra toda la linea"\M-k": kill-whole-line

    # Borra con la tecla DEL"\e[3~": delete-char

    4.1.2. Variables de readline

    readline tiene una serie de variables, que aparecen documentadas junto con

    las funciones de readline (y que tambin puede consultar usando Ctrl+XCtrl+V del ejemplo del apartado anterior), a las cuales podemos asignar un

  • 5/22/2018 Bash

    32/227

    El shell Bash MacProgramadores

    Pg 32

    valor en le fichero de configuracin de readline con set. Por ejemplo, unaopcin que algunas personas encuentran interesante en Mac OS X es evitarque al completar con tabulador distingan minsculas de maysculas. Es decir,si escribimos:

    $ cd mus

    Nos expanda a:$ cd Music/

    Para ello podemos aadir la siguiente lnea al fichero de configuracin dereadline:

    # Ignora diferencias de mayusculas/minusculas al# completar con tabulador

    set completion-ignore-case on

    4.2. Asignacin de teclas de sesin

    Si lo que queremos es probar combinaciones de teclas que no queremosalmacenar de forma permanente podemos usar el comando bind, cuyasintaxis es similar a la del fichero de configuracin, pero tenemos queencerrar cada asignacin entre comillas blandas o fuertes. Por ejemplo:

    $bind "\"\C-x\C-g\": dump-functions"

    Si queremos ver las asignaciones de teclas que hay hechas a cada funcin dereadline podemos usar el comando:

    $bind -P

    Este comando es muy til para que no asignemos una combinacin de teclasa otra que ya existe. Por ejemplo, en el apartado anterior para sacar lasfunciones de readline creamos la combinacin de teclas Ctrl+X Ctrl+F, pero al

    usar este comando descubrimos que ya exista la combinacin Ctrl+G quehace lo mismo:

    $bind -P!!!!!!!!!!!!!!!!!!dump-functions can be found on "\C-g", "\C-x\C-f".!!!!!!!!!!!!!!!!!!

    De hecho tambin podramos haber sacado las funciones de readline usandoel comando:

    $bind -l

  • 5/22/2018 Bash

    33/227

    El shell Bash MacProgramadores

    Pg 33

    Podemos sacar todas las asignaciones de teclas en formato inputrcusandoel comando:

    $bind -p

    En este caso sera muy til enviar esta salida a un fichero para posterior edi-cin:

    $bind -p > .inputrc

    Por ltimo comentar que podemos asignar combinaciones de teclas que eje-cutan comandos comunes con la opcin -x:

    $bind -x "\"\C-l\": ls -la"

    Ejecutar ls -laal pulsar Ctrl+L.

  • 5/22/2018 Bash

    34/227

    El shell Bash MacProgramadores

    Pg 34

    Tema 3Personalizar el

    entorno

    Sinopsis:

    En este tema veremos como hacer el entorno ms agradable personalizando

    distintos aspectos de Bash.

    Empezaremos viendo los ficheros que configuran Bash siempre que nos lo-gamos. Tambin veremos como personalizar distintos aspectos del compor-tamiento de Bash, y que variables de entornos participan en esta personaliza-cin.

    Este es el ltimo tema que dedicamos a aprender a manejar el terminal, elresto del tutorial enseara aspectos ms relativos a la programacin descripts con Bash.

  • 5/22/2018 Bash

    35/227

    El shell Bash MacProgramadores

    Pg 35

    1.Los ficheros de configuracin de Bash

    Cada vez que nos logamos en la cuenta se ejecuta el contenido del fichero

    /etc/profile, y luego se mira a ver si en el directorio home existe elfichero .bash_profile, de ser as se ejecuta su contenido para personalizaraspectos de nuestra cuenta.

    Cualquier configuracin que aadamos a .bash_profile no ser efectivahasta que salgamos de la cuenta y volvamos a logarnos, si hacemos cambiosen este fichero y queremos verlos sin salir de la cuenta podemos usar elcomando source, el cual ejecuta el contenido del fichero que le digamos:

    $ source .bash_profile

    Alternativamente al comando sourceest el comando punto (.), con lo queel contenido de .bash_profiletambin se podra haber ejecutado as:

    $ ..bash_profile

    Bash permite usar dos nombres alternativos para .bash_profile porrazones de compatibilidad histrica: .bash_login, nombre derivado delfichero .logindel C Shell, y .profilenombre usado por el Bourne Shell yel Korn Shell. En cualquier caso, slo uno de estos ficheros ser ejecutado: Si

    .bash_profileexiste los dems sern ignorados, sino Bash comprueba siexiste .bash_login y, slo si ste tampoco existe, comprueba si existe.profile. La razn por la que se eligi este orden de bsqueda es quepodemos almacenar en .profile opciones propias del Bourne Shell, yaadir opciones exclusivas de Bash en el fichero .bash_profile seguidodel comando source .profilepara que Bash tambin cargue las opcionesdel fichero .profile.

    .bash_profile se ejecuta slo al logarnos, si abrimos otro shell(ejecutando bash o su) desde la lnea de comandos de Bash lo que seintenta ejecutar es el contenido de .bashrc. Si .bashrc no existe no seejecutan configuraciones adicionales al abrir un nuevo shell. Este esquemanos permite separar configuraciones que se hacen una sola vez, al logarnos,de configuraciones que se cambian cada vez que se abre un nuevo shell. Sihay configuraciones en .bashrcque tambin queremos ejecutar al logarnospodemos poner source .bashrcdentro del fichero .bash_profile.

    Por ltimo, el fichero .bash_logoutes un fichero que, de existir, contieneordenes que se ejecutarn al abandonar la cuenta, por ejemplo eliminar

    ficheros temporales o almacenar datos de actividad de usuarios en un ficherode log.

  • 5/22/2018 Bash

    36/227

    El shell Bash MacProgramadores

    Pg 36

    2.Los alias

    Un alias es un nombre ms corto para un comando que usamos muy a

    menudo.

    Un ejemplo clsico de alias que se suele encontrar muchas veces en/etc/profilees:

    $ alias ll='ls -laF'

    Ahora podemos usar el alias llpara hacer un listado detallado del directorio.Otros dos alias bastante tiles son:

    $ alias ..="cd .."$ alias ...="cd .. ; cd .."

    Los alias son recursivos con lo que por ejemplo podemos hacer:

    $ alias l='ll'

    Aunque los alias slo pueden ser usados para representar comandos, si porejemplo intentamos representar un directorio largo con un alias, para luegometernos en el con cd, el comando fallar:

    $ alias ASCII='/usr/share/misc/ascii'$ cat ASCIIcat: ASCII: No such file or directory

    Existe un oscuro truco en Bash que permite hacer esto. Si la parte derecha dela asignacin del alias acaba con un espacio, entonces Bash intenta hacersustitucin de alias en la siguiente palabra del comando. Por ejemplo sihacemos:

    $ alias cat='cat '

    $ cat ASCII

    Obtendremos la tabla ASCII en pantalla.

    Si usamos el comando aliassin parmetros, obtenemos un listado de todoslos alias definidos. Si queremos conocer el valor de un determinado aliaspodemos usar el comando aliasseguido del nombre del alias sin smbolo =ni valor.

    $ alias ll

    alias ll='ls -laF'

  • 5/22/2018 Bash

    37/227

    El shell Bash MacProgramadores

    Pg 37

    Por ltimo, si queremos borrar la definicin de un alias podemos usar elcomando unalias:

    $ unalias ll

    3.Las opciones de Bash

    Las opciones del shell es una forma de poder modificar el comportamiento deste.

    Para fijar estas opciones usamos el comando shopt (shell option). Siejecutamos este comando sin argumentos obtendremos un listado de todaslas opciones del shell y su valor actual.

    Todas estas variables son booleanas y tienen valor de on/off. Podemosactivar estas opciones con shopt -s opciony desactivarlas con shopt -u opcion.

    La Tabla 3.1 muestra las principales opciones de shopt junto con unadescripcin de su propsito.

    Opcin Descripcincdable_vars Permite que cduse los valores de las variables

    como nombres de directorios.

    cdspell Ignora pequeos errores en los cambios dedirectorio con cd. Slo en la ejecucininteractiva.

    cmdhist Guarda los comandos que hemos escrito envarias lneas en una sola lnea del historial.

    dotglob Incluye en la expansin de comodines losficheros que empiezan por punto (.).

    expand_aliases Expande un alias cuando lo ejecuta.extglob Utiliza extensiones de los comodines. Vase

    apartado 2.4 del Tema 1. El trmino "glob"

    tambin se usa a veces para referirse a loscomodines.

    failglob Si falla la expansin de un comodn porque noencuentra nada falla el comando (como hace elC Shell).

    force_fignore Los sufijos especificados en la variable deentorno FIGNOREno se usan para completarpalabras con tabulador.

    hostcomplete Se intenta completar nombres de host al pulsartabulador cuando la palabra contiene una @.

    interactive_comments Permite que dentro de un comando de sesininteractiva haya comentarios (precedidos por #)

  • 5/22/2018 Bash

    38/227

    El shell Bash MacProgramadores

    Pg 38

    login_shell Variable de slo lectura que indica si Bash hasido lanzado como un shell de login

    nocaseglob Indica si los comodines expanden sinsensibilidad a maysculas/minsculas. Noconfundir con la variable completion-ignore-casede inputrcque lo que hacaera expandir con tabulador.

    nullglob Hace que cuando un patrn no encuentraficheros, se expandan por la cadena vaca en vezde por el patrn sin expandir.

    sourcepath Hace que el comando interno sourcebusque elargumento en los directorios que indique PATH

    Tabla 3.1: Principales opciones de shopt

    Una opcin que resulta muy til es cdable_vars, la cual permite que elcomando cd use los valores de las variables como nombres de directorios.Esto se usa cuando hay un directorio al que solemos movernos mucho. Porejemplo si tenemos el directorio /usr/local/mldonkey/incomming alque solemos ir muy a menudo desde la consola podemos definir en losficheros de configuracin de Bash:

    # Para ir a mldonkeyexport DONKEY=/usr/local/mldonkey/incommingshopt -s cdable_vars

    Y ahora para movernos a este directorio basta con hacer:

    $ cd DONKEY

    Obsrvese que DONKEYno va precedida por $.

    Otra opcin muy til es cdspell que permite que se ignoren pequeoserrores en los directorios que indicamos a cd. Por ejemplo este pequeo bailede letras es corregido por cd:

    $ cd /usr/locla/share//usr/local/share/

    Esta opcin slo funciona en modo interactivo.

  • 5/22/2018 Bash

    39/227

    El shell Bash MacProgramadores

    Pg 39

    4.Las variables de entorno

    Las variables de entorno nos ayudan a configurar el entorno en el que se eje-

    cutan los programas.

    Para declararlas es importante recordar que las variables de entorno no pue-den tener espacios, y si queremos asignar un valor con espacio debemos deentrecomillarlo, o bien preceder el espacio por un carcter de escape:

    $NOMBRE='Fernando Lopez'$ echo $NOMBREFernando Lopez$NOMBRE=Fernando\ Lopez$ echo $NOMBREFernando Lopez

    Como sabemos, para obtener el valor de una variable debemos de precederlapor $. Obsrvese que las comillas o el carcter de escape no forman parte delvalor de la variable una vez que se realiza la asignacin.

    Para eliminar una variable de entorno podemos usar el comando unset. Porejemplo:

    $ unset NOMBRE

    4.1. Variables y entrecomillado

    En el apartado 6.1 del Tema 1 comentamos que las comillas dobles (las dbi-les) interpretaban algunos de los caracteres que contenan. Uno de ellos es elcarcter $, el cual nos permite expandir el valor de una variable dentro deuna cadena. Por ejemplo:

    $ articulo='Zapatos negros'

    $precio=20.5$ echo "El articulo $articulo cuesta $precio euros"El articulo Zapatos negros cuesta 20.5 euros

    4.2. Personalizar el prompt

    Podemos personalizar el prompt de Bash usando las variables de entornoPS1, PS2, PS3y PS4. La Tabla 3.2 muestra las opciones de personalizacinque podemos usar en cualquiera de los prompt.

  • 5/22/2018 Bash

    40/227

    El shell Bash MacProgramadores

    Pg 40

    En el prompt podemos encontrar mucha opciones que nos ayudan a trabajar,quiz la ms usada es \wque muestra le directorio donde estamos situadosen cada momento.

    $ PS1='\w->'

    ~->

    Donde ~significa que estamos en el directorio home.

    Es muy tpico querer saber si somos root o cualquier otro usuario de la m-quina, para lo cual se usa la opcin \$que muestra una #si somos root, o un$en cualquier otro caso.

    ~->PS1='\w\$'~$

    Muchas veces el prompt nos ayuda a saber en que mquina estamos situa-dos, esto es til por ejemplo cuando tenemos la costumbre de hacer muchostelnet o ssh a otras mquinas. En este caso podemos usar la opcin \Hquenos da el nombre de la mquina donde estamos situados, o la opcin \hquenos da el nombre de la mquina slo hasta el primer punto:

    ~$ PS1='\h\w\$'macbox~$ PS1='\H\w\$'macbox.macprogramadores.org~$

    Aunque en Mac OS X no es muy til, cuando trabajamos con una mquinaUNIX en modo slo consola solemos poder movernos por un conjunto de 6terminales virtuales usando las teclas Ctrl+F1 hasta Ctrl+F6 (o Alf+F1 hastaAlf+F6 en algunas configuraciones). En estos casos s que es recomendableconocer el nombre del terminal con la opcin \l. Por ejemplo en mi FreeBSDtengo este prompt:

    [root@freebsd@ttyv0]~# echo $PS1[\u@\h@\l]\w\$

    Donde me indica el usuario con el que estoy logado (opcin \u), la maquinadonde estoy, y el terminal virtual donde estoy trabajando.

    En mi Mac OS X tengo este otro prompt:

    $ echo $PS1[\u@\h]\w\$[fernando@macbox]~$

    Donde me indica el usuario con el que estoy logado y el host, pero no el ter-

    minal virtual.

  • 5/22/2018 Bash

    41/227

    El shell Bash MacProgramadores

    Pg 41

    Si estamos trabajando con el comando fc(vase apartado 1.1 del Tema 2)podra ser til usar \! que nos va dando el nmero histrico del comandoque vamos a ejecutar.

    Opcin Descripcin\a El carcter ASCII bell (007)\A La hora en formato HH:MM\d La fecha en formato semana mes dia\D {formato} Nos permite personalizar ms la fecha\e El carcter de escape ASCII (033)\H Hostname\h El nombre de la mquina hasta el primer punto\j Nmero de jobs hijos del shell

    \l Nombre del terminal en el que estamos trabajando (p.e.ttyp2)\n Retorno de carro y cambio de lnea\r Retorno de carro\s Nombre del shell\t Hora en formato HH:MM:SScon 12 horas\T Hora en el formato anterior pero con 24 horas\u Nombre de usuario\v Versin de Bash\w Ruta del directorio actual

    \W Nombre del directorio actual (sin ruta)\# Nmero de comandos ejecutados\! Nmero histrico del comando\$ #si somos root, o $en caso contrario\nnn Cdigo de carcter a mostrar en octal\\ La barra haca atrs\[ Empieza una secuencia de caracteres no imprimibles, como

    los caracteres de control de secuencias del terminal\] Acaba una secuencia de caracteres no imprimibles

    Tabla 3.2: Opciones de personalizacin del prompt

    PS2es el prompt secundario y por defecto vale >. Se usa cuando usamos elmodo de entrada multilnea, en el que entramos al escribir un comandoinacabado, por ejemplo vimos:

    $ echo En un lugar de la Mancha de cuyo nombre no \> quiero acordarme no a mucho tiempo viva un \> hidalgo caballero.En un lugar de la Mancha de cuyo nombre no quiero acordarno a mucho tiempo viva un hidalgo caballero.

  • 5/22/2018 Bash

    42/227

    El shell Bash MacProgramadores

    Pg 42

    Por ltimo, PS3y PS4son prompts de programacin y depuracin que estu-diaremos en temas posteriores.

    4.3. Variables de entorno internas

    Existen una serie de variables de entorno, las cuales se resumen en la Tabla3.3, que no las fijamos nosotros sino que las fija el shell, y cuyo valor es deslo lectura.

    Variable DescripcinSHELL Path del fichero que estamos usandoLINES Lneas del terminal en caracteresCOLUMNS Columnas del terminal en caracteresHOME Directorio home del usuario

    PWD Directorio actualOLDPWD Anterior directorio actualUSER Nombre de usuario en la cuenta donde estamos logados

    Tabla 3.3:Variables de entorno internas

    Algunas variables se actualizan dinmicamente, por ejemplo LINES yCOLUMNSen todo momento almacenan en nmero de filas y columnas de lapantalla, y las usan algunos programas como vi o emacs para modificar suapariencia.

    4.4. Exportar variables

    Las variables de entorno que definimos dentro de una sesin de Bash no es-tn disponibles para los subprocesos que lanza Bash (slo las puede usarBash y nuestros comandos interactivos y scripts) a no ser que las exportemoscon el comando export. Por ejemplo:

    $ EDITOR=/sw/bin/joe$ export EDITOR

    Tambin podemos exportar una variable de entorno a la vez que la asigna-mos un valor as:

    $ export EDITOR=/sw/bin/joe

    Podemos obtener un listado de las variables exportadas usando el comandoenvo el comando exportsin argumentos. Para obtener las variables tantoexportadas como no exportadas debemos usar el comando setsin argumen-tos.

  • 5/22/2018 Bash

    43/227

    El shell Bash MacProgramadores

    Pg 43

    Tema 4Programacin

    bsica del shell

    Sinopsis:

    Este tema introduce los conceptos ms bsicos de la programacin de scriptsy funciones con Bash.

    En este momento debera de ser capaz de manejarse con el terminal (el modointeractivo) con ms soltura que antes de leer este tutorial. Ahora pretende-mos empezar a entender los scripts que configuran su mquina, y a que sea

    capaz de crear sus propios scripts.

    El tema supone que el lector conoce los conceptos bsicos de programacinen algn lenguaje estructurado (C, Pascal, Basic). Bash no usa los conceptosde programacin orientada a objetos, pero si conoce este tipo de programa-cin (p.e. Java) tambin le servir aqu, ya que la programacin estructuradaes un subconjunto de la orientada a objetos.

    Bash es un lenguaje muy crptico, con lo que sera recomendable que se fijarabien en la sintaxis, y que intentara hacer los ejercicios que proponemos en su

    ordenador con el fin de consolidad las ideas bsicas que vamos a desarrollaren este tema.

  • 5/22/2018 Bash

    44/227

    El shell Bash MacProgramadores

    Pg 44

    1.Scripts y funciones

    1.1. Scripts

    Un script es un fichero que contiene comandos Bash ejecutables. Losficheros de configuracin de Bash como .bash_profileo .bashrc, vistosen el apartado 1 del Tema 3, son ejemplos de scripts.

    Para crear un script use su editor de texto favorito, y guardelo en un fichero.Una vez creado el script existen dos formas de ejecutarlo:

    La primera consiste en ejecutarlo con el comando source fichero, el cual

    carga el fichero en la memoria de Bash y lo ejecuta.

    La segunda forma implica poner al fichero permiso de ejecucin (con elcomando chmod +x fichero). Una vez puesto este permiso, podremosejecutarlo siempre que est en alguno de los directorios indicados en lavariable de entorno PATH. De hecho muchos comandos comunes (p.e. spello man) estn implementados como scripts Bash, y no como programas Cejecutables. Es muy tpico en este caso empezar el script poniendo en laprimera lnea #! /bin/bash, de esta forma indicamos que el script se debeejecutar con Bash, a pesar de que Bash no fuera el shell por defecto. Otros

    scripts para otros lenguajes como awk, ksh o perl tambin se escribenempezando la primera lnea por el path del shell a utilizar.

    Hay otra diferencia entre estas dos formas de ejecutarlo: Cuando ejecutamosun script con source, ste se ejecuta dentro del proceso del shell, mientrasque si lo ejecutamos como un fichero ejecutable se ejecuta en un subshell.Esto implica que slo las variables de entorno exportadas son conocidas porel nuevo subshell que ejecuta el programa.

    De hecho, cada vez que un script llama a un comando tambin se ejecuta en

    un proceso aparte, excepto con los comandos internos que se ejecutandentro del proceso del script, lo cual les hace ms rpidos y les permiteacceder a las variables de entorno no exportadas.

    1.2. Funciones

    Las funciones de Bash son una extensin de las funciones que existen desdeel Bourne Shell.

    stas, a diferencia de los scripts, se ejecutan dentro de la memoria del propio

    proceso de Bash, con lo que son ms eficientes que ejecutar scripts aparte,pero tienen el inconveniente de que tienen que estar siempre cargadas en la

  • 5/22/2018 Bash

    45/227

    El shell Bash MacProgramadores

    Pg 45

    memoria del proceso Bash para poder usarse. Actualmente, debido a la grancantidad de memoria que tienen los ordenadores, el tener funciones cargadasen la memoria de Bash tiene un coste insignificante, con lo que no debera depreocuparle el tener cargadas gran cantidad de estas en su entorno.

    Para definir una funcin existen dos formatos:

    El estilo del Bourne Shell;

    function nombrefn{!!!comandos bash!!!}

    O el estilo del C Shell:

    nombrefn() {!!!comandos bash!!!

    }

    No existe diferencia entre ellos, y usaremos ambos indistintamente. Paraborrar una funcin podemos usar el comando unset -f nombrefn.

    Cuando definimos una funcin se almacena como una variable de entorno(con su valor almacenando la implementacin de la funcin). Para ejecutar lafuncin simplemente escribimos su nombre seguido de argumentos, comocuando ejecutamos un comando. Los argumentos actan como parmetrosde la funcin.

    Podemos ver que funciones tenemos definidas en una sesin usando el

    comando declare -f. El shell imprime las funciones, y su definicin,ordenadas alfabticamente. Si preferimos obtener slo el nombre de lasfunciones podemos usar el comando declare -F.

    Si una funcin tiene el mismo nombre que un script o ejecutable, la funcintiene preferencia: Esta regla se ha usado muchas veces para, engaando alos usuarios, violar la integridad de su sistema.

    1.3. Orden de preferencia de los smbolos de Bash

    A continuacin se enumera el orden de preferencia que sigue Bash a la horade resolver un smbolo:

    1.Alias.2. Palabras clave (keywords) como function, ifo for.3. Funciones4. Comandos internos (p.e. cdo type).5. Scripts y programas ejecutables, para los cuales se sigue el orden en

    que se dan sus directorios en la variable de entorno PATH.

  • 5/22/2018 Bash

    46/227

    El shell Bash MacProgramadores

    Pg 46

    Aunque no es muy comn, a veces conviene cambiar estos ordenes usandolos comandos internos command, builtiny enable. Esto nos permite teneralias y scripts con el mismo nombre y elegir cual de ellos ejecutar. En poste-riores temas veremos su utilidad.

    Si nos interesa conocer la procedencia de un comando podemos usar el co-mando interno type. Si le damos un comando nos indica cual es su fuente, sile damos varios nos indica la fuente de cada no de ellos. Por ejemplo:

    $ type lsls is /bin/ls$ type ls llls is /bin/lsll is aliased to `ls -laF'

    Si tenemos un script, una funcin y un alias llamados hazlo, typenos dirque est usando hazlocomo alias, ya que los alias tienen preferencia sobreel resto de smbolos:

    $type hazlohazlo is aliased to `rm *'

    type tambin tiene opciones que nos permiten obtener detalles de unsmbolo. Si queremos conocer todas las definiciones de un smbolo podemosusar type -a. Por ejemplo:

    $ type -a hazlohazlo is aliased to `rm *'hazlo is a functionhazlo () {

    rm *}hazlo is ./hazlo

    Podemos conocer el tipo de un smbolo con la opcin -t: Nos devolveralias, keyword, function, builtino file. Por ejemplo:

    $ type -t cdbuiltin$ type -t cpfile

  • 5/22/2018 Bash

    47/227

    El shell Bash MacProgramadores

    Pg 47

    2.Variables del shell

    Principalmente Bash utiliza variables de tipo cadena de caracteres. Esto le di-

    ferencia de otros lenguajes de programacin donde las variables tienen distin-tos tipos. Aunque ste es el tipo por defecto de las variables de Bash, msadelante veremos que las variables en Bash tambin pueden tener otros ti-pos, como por ejemplo enteros con los que realizar operaciones aritmticas.

    Por convenio las variables de entorno exportadas (las que pasamos a los sub-procesos) se escriben en maysculas, y las que no exportamos en minscu-las. Esta regla, ms que por el modo interactivo, es especialmente seguidapor los scripts y funciones que vamos a empezar a programar ahora.

    2.1. Los parmetros posicinales

    Los parmetros posicinalesson los encargados de recibir los argumentosde un script y los parmetros de una funcin. Sus nombres son 1, 2, 3, etc.,con lo que para acceder a ellos utilizaremos, como normalmente, el smbolo $de la forma $1, $2, $3, etc. Adems tenemos el parmetro posicional 0quealmacena el nombre del script donde se ejecuta.

    Por ejemplo imaginemos que creamos el script del Listado 4.1:

    #!/bin/bash# Ejemplo de script que recibe parametros y los imprime

    echo "El script $0"echo "Recibe los argumentos $1 $2 $3 $4"

    Listado 4.1: Script que recibe argumentos

    Si lo hemos guardado en un fichero llamado recibecon el permiso xactiva-do podemos ejecutarlo as:

    $ recibe hola adiosEl script ./recibeRecibe los argumentos hola adios

    Como los argumentos $3y $4no los hemos pasado son nulos que dan lugara una cadena vaca que no se imprime.

    Para definir una funcin podemos escribirla en un fichero y cargarla en elshell usando el comando source, o bien definirla directamente en modo in-

    teractivo:

  • 5/22/2018 Bash

    48/227

    El shell Bash MacProgramadores

    Pg 48

    $ function recibe{> echo "La funcion $0"> echo "Recibe los argumentos $1 $2 $3 $4"> }$ recibe buenos dias Bash

    La funcion -bashRecibe los argumentos buenos dias Bash

    El modo de entrada multilnea (que explicamos en el apartado 4.2 del Tema3) hace que el shell nos vaya pidiendo lneas hasta que cerramos la llave. Du-rante este modo aparecer el prompt secundario (>).

    Como los nombres de funciones tienen preferencia sobre los de los scriptsahora se ejecuta la funcin recibe() y no el script recibe. Vemos queahora $0no se ha sustituido por el nombre de la funcin sino por -bash, es-

    to es as porque $0siempre se sustituye por el nombre de script (no el de lafuncin), o -bashsi lo ejecutamos directamente desde la lnea de comandos.

    Por ltimo comentar que no podemos modificar el valor de las variables posi-cinales, slo se pueden leer, si intentamos asignarlas un valor se produce unerror.

    2.2. Variables locales y globales

    Por defecto los parmetros posicinales son locales al script o funcin y no sepueden acceder o modificar desde otra funcin. Por ejemplo en el Listado 4.2vemos un script, que guardaremos en el fichero saluda, que llama a unafuncin para que salude al nombre que pasamos al script como argumento en$1:

    # Script que llama a una funcion para saludar

    function DiHola {echo "Hola $1"

    }

    DiHola

    Listado 4.2: Script que llama a una funcin para saludar

    Al ejecutarlo obtenemos:

    $ saluda FernandoHola

  • 5/22/2018 Bash

    49/227

    El shell Bash MacProgramadores

    Pg 49

    Vemos que el argumento pasado en $1no a sido cogido por la funcin, esoes porque $1es local al script, y si queremos que lo reciba la funcin ten-dremos que pasrselo como muestra el Listado 4.3.

    # Script que llama a una funcion para saludar

    function DiHola {echo "Hola $1"}

    DiHola $1

    Listado 4.3: Script que pasa el argumento a una funcin para que salude

    A diferencia de los parmetros posicinales, el resto de variables que defini-

    mos en un script o funcin son globales, es decir una vez definidas en elscript son accesibles (y modificables) desde cualquier funcin. Por ejemplo,en el Listado 4.4 se muestra un script llamado dondeestoy, en el que la va-riable dondeest definida por el script y modificada por la funcin.

    # Ejemplo de variable global

    function EstasAqui {donde='Dentro de la funcion'}

    donde='En el script'echo $dondeEstasAquiecho $donde

    Listado 4.4: Ejemplo de variable global

    Al ejecutarlo obtenemos:

    $ dondeestoyEn el scriptDentro de la funcion

    Si queremos que una variable no posicional sea local debemos de ponerla elmodificador local, el cual slo se puede usar dentro de las funciones (no enlos scripts). Por ejemplo en el Listado 4.5 ahora la funcin se crea su propiavariable local dondey no modifica la global del script.

    # Ejemplo de variable global

    function EstasAqui {

    localdonde='Dentro de la funcion'}

  • 5/22/2018 Bash

    50/227

    El shell Bash MacProgramadores

    Pg 50

    donde='En el script'echo $dondeEstasAquiecho $donde

    Listado 4.5: Ejemplo de variable local y global con el mismo nombre

    Al ejecutarlo obtenemos:

    $ dondeestoyEn el scriptEn el script

    Por ltimo comentar que las variables globales tambin se pueden definir de-ntro de una funcin. Por ejemplo, en el Listado 4.6 se muestra como defini-mos la variable global quiensoy dentro de la funcin EstasAqui() y lausamos ms tarde desde el script.

    # Ejemplo de variable global

    function EstasAqui {local donde='Dentro de la funcion'quiensoy=Fernando}

    donde='En el script'echo $dondeEstasAquiecho $dondeecho "Soy $quiensoy"

    Listado 4.6: Ejemplo de variable global definida dentro de una funcin

    Al ejecutar el script del Listado 4.6 obtenemos:

    $ dondeestoy

    En el scriptEn el scriptSoy Fernando

    2.3. Las variables $*, $@y $#

    La variable $# almacena el nmero de argumentos o parmetros recibidospor el script o la funcin. El valor es de tipo cadena de caracteres, pero msadelante veremos como podemos convertir este valor a nmero para operar

    con l.

  • 5/22/2018 Bash

    51/227

    El shell Bash MacProgramadores

    Pg 51

    Tanto $* como $@ nos devuelven los argumentos recibidos por el script ofuncin. Cuando no se entrecomillan se comportan exactamente igual, pero alencerrarlos en comillas dbiles "$*"crea un nico token que corresponde atodos los argumentos recibidos mientras que "$@" crea un token por cadaargumento recibido.

    Normalmente $*como $@se utilizan con el bucle for(que se explica en elapartado 2 del Tema 5). El Listado 4.7 muestra cmo se comporta cada unade estas variaciones con los argumetos recibidos.

    for i in $@; do echo "\$@ $i"; donefor i in $*; do echo "\$* $i"; donefor i in "$@"; do echo "\"\$@\" $i"; donefor i in "$*"; do echo "\"\$*\" $i"; done

    Listado 4.7: Ejemplo de uso de $*y $@

    Al ejecutarlo obtenemos:

    $ ./recibe hola adios$@ hola$@ adios$* hola$* adios"$@" hola"$@" adios"$*" hola adios

    Cuando los encerramos entre comillas dbiles existen dos diferencias queconviene resaltar:

    La primera es que podemos cambiar el smbolo que usa "$*"para separarlos argumentos indicndolo en la variable de entorno IFS(Internal Field Se-parator), mientras que "$@" siempre usa como separador un espacio. Porejemplo si hacemos el siguiente script:

    IFS=','echo "El script $0 recibe $# argumentos: $*"echo "El script $0 recibe $# argumentos: $@"

    Al ejecutarlo obtenemos:

    $ recibe hola adiosEl script ./recibe recibe 2 argumentos: hola,adiosEl script ./recibe recibe 2 argumentos: hola adios

    La segunda diferencia se produce al recoger los argumentos para pasrselosa una funcin. Imaginemos que tenemos definida la siguiente funcin:

  • 5/22/2018 Bash

    52/227

    El shell Bash MacProgramadores

    Pg 52

    function CuentaArgumentos {echo "Recibidos $# argumentos"}

    Ahora podemos pasar los argumentos recibidos por el script a la funcinusando cualquiera de las dos variables:

    CuentaArgumentos $*CuentaArgumentos $@

    Y al ejecutarlo obtenemos:

    $ recibe hola adiosRecibidos 2 argumentosRecibidos 2 argumentos

    Pero el no encerrar tanto $*como $@entre comillas al llamar a una funcintiene un efecto lateral por el que no se recomienda. Este efecto se producecuando recibimos argumentos que contienen espacios:

    $ recibe "El perro" "La casa"Recibidos 4 argumentosRecibidos 4 argumentos

    El problema est en que se pierden las comillas de las variables y se interpre-

    ta cada token como un parmetro de la funcin.

    Sin embargo, si entrecomillamos $*y $@:

    CuentaArgumentos "$*"CuentaArgumentos "$@"

    Obtenemos el siguiente resultado:

    $ recibe "El perro" "La casa"

    Recibidos 1 argumentosRecibidos 2 argumentos

    Es decir, "$*"tiene el efecto de que se convierte en un slo token, mientrasque con "$@"cada argumento es un token.

    En consecuencia obtenemos las siguientes reglas generales:

    1. Siempre conviene usar las variables "$*"y "$@"entrecomilladas paraevitar que los argumentos que contengan espacios sean mal interpre-

    tados.

  • 5/22/2018 Bash

    53/227

    El shell Bash MacProgramadores

    Pg 53

    2. Si queremos cambiar el delimitador que separa los argumentos (usan-do IFS) debemos utilizar "@*"entrecomillado.

    3. Si lo que queremos es pasar los argumentos a una funcin debemos deusar "$@"entrecomillado.

    2.4. Expansin de variables usando llaves

    Realmente la forma que usamos para expandir una variable $variable esuna simplificacin de la forma ms general ${variable}. La simplificacinse puede usar siempre que no existan ambigedades. En este apartado ve-remos cuando se producen las ambigedades que nos obligan a usar la forma${variable}.

    La forma ${variable}se usa siempre que la variable vaya seguida por una

    letra, dgito o guin bajo (_), en caso contrario podemos usar la forma simpli-ficada $variable. Por ejemplo si queremos escribir nuestro nombre (alma-cenado en la variable nombre) y nuestro apellido (almacenado en la variableapellido) separados por un guin podramos pensar en hacer:

    $ nombre=Fernando$ apellido=Lopez$ echo "$nombre_$apellido"Lopez

    Pero esto produce una salida incorrecta porque Bash ha intentado buscar lavariable $nombre_que al no existir la ha expandido por una cadena vaca.

    Para solucionarlo podemos usar las llaves:

    $ echo "${nombre}_$apellido"Fernando_Lopez

    Otro lugar donde necesitamos usar llaves es cuando vamos a sacar el dcimoparmetro posicional. Si usamos $10, Bash lo expandir por $1 seguido deun

    0, mientras que si usamos

    ${10}Bash nos dar el dcimo parmetro po-

    sicional.

  • 5/22/2018 Bash

    54/227

    El shell Bash MacProgramadores

    Pg 54

    3.Operadores de cadena

    Los operadores de cadenanos permiten manipular cadenas sin necesidad

    de escribir complicadas rutinas de procesamiento de texto. En particular losoperadores de cadena nos permiten realizar las siguientes operaciones:

    Asegurarnos de que una variable existe (que est definida y que no esnula).

    Asignar valores por defecto a las variables. Tratar errores debidos a que una variable no tiene un valor asignado Coger o eliminar partes de la cadena que cumplen un patrn

    Vamos a empezar viendo los operadores de sustitucin, para luego ver los de

    bsqueda de cadenas.3.1. Operadores de sustitucin

    La Tabla 4.1 muestra los operadores de sustitucin.

    Operador Descripcin$ {var:-valor} 2 Si varexiste y no es nula retorna su valor,

    sino retorna valor.$ {var:+valor} 1 Si varexiste y no es nula retorna valor,

    sino retorna una cadena nula.$ {var:=valor} 1 Si varexiste y no es nula retorna su valor,

    sino asigna valora variabley retornasu valor.

    $ {var:?mensaje} 1 Si varexiste y no es nula retorna su valor,sino imprime var:mensajey aborta elscript que se est ejecutando (slo enshells no interactivos). Si omitimosmensajeimprime el mensaje por defectoparameter null or not set.

    $ {var:offset:longitud} Retorna una subcadena de varque empie-za en offsety tiene longitudcaracte-res. El primer carcter de varempieza enla posicin 0. Si se omite longitudlasubcadena empieza en offsety continuahasta el final de var.

    Tabla 4.1: Operadores de sustitucin

    2Los dos puntos (:) en este operador son opcionales.