Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Articulo Programación Bash Shell, Apuntes de Sistemas Operativos

Articulo Programación Bash_Shell

Tipo: Apuntes

2018/2019

Subido el 15/03/2019

claudiamora
claudiamora 🇨🇴

1 documento

1 / 168

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
El shell Bash
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e
pf4f
pf50
pf51
pf52
pf53
pf54
pf55
pf56
pf57
pf58
pf59
pf5a
pf5b
pf5c
pf5d
pf5e
pf5f
pf60
pf61
pf62
pf63
pf64

Vista previa parcial del texto

¡Descarga Articulo Programación Bash Shell y más Apuntes en PDF de Sistemas Operativos solo en Docsity!

El shell Bash

Acerca de este documento

En este tutorial pretendemos enseñar el manejo de Bash, el Bourne Again Shell de GNU. Este shell es el que proporcionan por defecto muchos sistemas UNIX entre ellos Mac OS X o Linux. Los ejemplos se explicarán sobre Mac OS X, pero debido a la interoperatividad que caracteriza a Bash, estos ejemplos deberían ser exactamente igual de útiles en otros sistemas UNIX. Cuando existan diferencias las indicaremos para que usuarios de otros sistemas puedan seguir correctamente este documento. El tutorial asume que el lector conoce los aspectos más básicos de qué es, y para qué sirve un terminal. No pretendemos enseñar cuales son los muchos y útiles comandos a los que podemos acceder, sólo pretendemos centrarnos en el manejo, personalización y programación de scripts con el shell Bash. Aun así, a lo largo del documento comentaremos gran cantidad de comandos que están relacionados con el shell, y que ayudan a hacer que los ejemplos resulten útiles. Al acabar este tutorial el lector debería de haber aprendido a usar las principales teclas rápidas, personalizar mucho más su terminal para hacerlo más manejable, y modificar o crear los scripts que configuran su sistema.

Nota legal

Este tutorial ha sido escrito por Fernando López Hernández para MacProgramadores, y de acuerdo a los derechos que le concede la legislación española e internacional el autor prohíbe la publicación de este documento en cualquier otro servidor web, así como su venta, o difusión en cualquier otro medio sin autorización previa. Sin embargo el autor anima a todos los servidores web a colocar enlaces a este documento. El autor también anima a cualquier persona interesada en conocer el shell Bash, y que ventajas que aporta tanto al usuario como al programador, a bajarse o imprimirse este tutorial. Madrid, Enero 2009 Para cualquier aclaración contacte con: [email protected]

    1. El shell que estamos usando TEMA 1: Introducción a Bash
    1. Expansión de nombres de ficheros y directorios...................................
    • 2.1. Los comodines
    • 2.2. El comodín tilde...........................................................................
    • 2.3. El comodín llaves.........................................................................
    • 2.4. Comodines extendidos
    1. Los comandos internos de Bash..........................................................
    1. Redirecciones y pipes.........................................................................
    • 4.1. Operadores de redirección
    • 4.2. Pipes
    1. Ejecución secuencial y concurrente de comandos
    1. Caracteres especiales y entrecomillado
    • 6.1. Entrecomillado
    • 6.2. Caracteres de escape...................................................................
    • 6.3. Entrecomillar los entrecomillados..................................................
    • 6.4. Texto de varias líneas
    1. El historial de comandos TEMA 2: Combinaciones de teclas
    • 1.1. El comando fc............................................................................
    • 1.2. Ejecutar comandos anteriores
    1. Las teclas de control del terminal........................................................
    1. Modos de edición en la línea de comandos
    • 3.1. Moverse por la línea
    • 3.2. Borrar partes de la línea
    • 3.3. Buscar en el historial
    • 3.4. Autocompletar con el tabulador....................................................
    1. La librería readline
    • 4.1. El fichero de configuración
    • 4.2. Asignación de teclas de sesión
    1. Los ficheros de configuración de Bash................................................. TEMA 3: Personalizar el entorno
    1. Los alias............................................................................................
    1. Las opciones de Bash.........................................................................
    1. Las variables de entorno
    • 4.1. Variables y entrecomillado
    • 4.2. Personalizar el prompt
    • 4.3. Variables de entorno internas.......................................................
    • 4.4. Exportar variables
    1. Scripts y funciones............................................................................. TEMA 4: Programación básica del shell
    • 1.1. Scripts
    • 1.2. Funciones
    • 1.3. Orden de preferencia de los símbolos de Bash
    1. Variables del shell..............................................................................
    • 2.1. Los parámetros posiciónales.........................................................
    • 2.2. Variables locales y globales
    • 2.3. Las variables $*, $@ y $#
    • 2.4. Expansión de variables usando llaves............................................
    1. Operadores de cadena
    • 3.1. Operadores de sustitución............................................................
    • 3.2. Operadores de búsqueda de patrones...........................................
    • 3.3. El operador longitud
    1. Sustitución de comandos....................................................................
    1. Las sentencias condicionales TEMA 5: Control de flujo
    • 1.1. Las sentencias if, elif y else..................................................
    • 1.2. Los códigos de terminación
    • 1.3. Las sentencias return y exit....................................................
    • 1.4. Operadores lógicos y códigos de terminación
    • 1.5. Test condicionales
    1. El bucle for......................................................................................
    1. Los bucles while y until
    1. La sentencia case.............................................................................
    1. La sentencia select.........................................................................
    1. Opciones de la línea de comandos TEMA 6: Opciones de línea de comandos, expresiones aritméticas y arrays
    • 1.1. La sentencia shift.....................................................................
    • 1.2. El comando interno getopts
    1. Variables con tipo
    1. Expresiones aritméticas......................................................................
    • 3.1. Similitud con las expresiones aritméticas C....................................
    • 3.2. El comando interno let
    • 3.3. Sentencias de control de flujo aritméticas
    • 3.4. Arrays........................................................................................
    1. Redirecciones TEMA 7: Redirecciones
    • 1.1. Los descriptores de fichero
    • 1.2. El comando exec.......................................................................
    • 1.3. Here documents.........................................................................
    1. Entrada y salida de texto...................................................................
    • 2.1. El comando interno echo
    • 2.2. El comando interno printf
    • 2.3. El comando interno read
    1. Los bloques de comandos
    1. Los comandos comand, builtin y enable
    1. El comando interno eval..................................................................
    1. IDs de procesos y números de jobs TEMA 8: Control de procesos
    1. Control de jobs.................................................................................
    • 2.1. Foreground y background
    • 2.2. Suspender y reanudar un job
    • 2.3. El comando ps...........................................................................
    • 2.4. El comando top.........................................................................
    1. Señales
    • 3.1. Combinaciones de teclas que envían señales................................
    • 3.2. El comando interno kill
    1. Capturar señales desde un script
    • 4.1. El comando interno trap
    • 4.2. Traps y funciones
    • 4.3. IDs de proceso...........................................................................
    • 4.4. Ignorar señales
    1. Reatachar sesiones del terminal
    1. Corutinas
    1. Subshells
    1. La sustitución de procesos
    1. Opciones de Bash para depuración TEMA 9: Depurar scripts
    1. Fake signals
    • 2.1. La señal SIGEXIT......................................................................
    • 2.2. La señal SIGERR........................................................................
    • 2.3. La señal SIGDEBUG....................................................................
    • 2.4. La señal SIGRETURN..................................................................
    1. Un depurador Bash...........................................................................
    • 3.1. Estructura del depurador
    • 3.2. El driver.....................................................................................

Tema 1

Introducción a

Bash

Sinopsis: Como se justifica en el acerca de, este tutorial va a omitir los aspectos más básicos del shell que es normal conocer por parte de cualquier persona que haya usado mínimamente un shell UNIX. En este primer tema vamos a repasar un conjunto de aspectos fundamentales que, aunque en parte puede conocer el lector, creemos que conviene aclarar antes de profundizar. Por consiguiente, recomendamos empezar leyendo este primer tema, ya que sino pueden quedar ciertos aspectos sin concretar que luego podrían hacer falta para seguir más cómodamente las explicaciones. Debido a sus objetivos, este tema está escrito avanzando de forma considerablemente más rápida y superficial que en resto de temas.

1. El shell que estamos usando

Mac OS X trae preinstalado el shell Bash desde la versión 10.2, antes traía instalado el shell tcsh, pero debido a que Bash es el shell que GNU eligió para el software libre, Apple decidió dar el salto. Linux lógicamente también usa este shell, con lo cual parece ser que Bash es el shell de los sistemas UNIX más utilizados, y tiene un futuro muy prometedor. Si queremos saber que versión de shell tenemos instalado podemos usar el comando: $ echo $SHELL /bin/bash Este comando nos indica que shell estamos usando y en que directorio está instalado. Si queremos conocer la versión de Bash podemos usar el comando: $ echo $BASH_VERSION 2.05b.0(1)-release También podemos saber donde está instalado Bash con el comando: $ whereis bash /bin/bash Puede conocer todos los shell de que dispone su máquina con el comando: $ cat /etc/shells /bin/bash /bin/csh /bin/sh /bin/tcsh /bin/zsh Si por alguna razón no está usando Bash, pero lo tiene instalado (o lo acaba de instalar) en su máquina, puede hacer que Bash sea el shell por defecto de su cuenta usando el comando: $ chsh - s /bin/bash Si prefiere usar una versión más moderna de shell que la que viene preinstalada con Mac OS X puede bajársela del proyecto Fink^1 : (^1) Si no tiene Fink instalado puede bajárselo de http://fink.sourceforge.net/

2. Expansión de nombres de ficheros y

directorios

2.1. Los comodines

Para referirnos a varios ficheros es muy típico usar los comodines de la Tabla

    1. Un sitio típico donde se usan los comodines es el comando ls. Este comando sin argumentos lista todos los ficheros del directorio, pero le podemos pasar como argumentos los nombres de los ficheros que queremos listar: $ ls carta.txt leeme.txt Si lo que le damos son los nombres de uno o más directorios lo que hace es listar su contenido. Comodín Descripción ? (^) Uno y sólo un carácter
  • (^) Cero o más caracteres [ conjunto ] (^) Uno los caracteres de conjunto [! conjunto ] (^) Un carácter que no este en conjunto Tabla 1. 1 : Comodines de fichero Muchas veces queremos referirnos a un conjunto de ficheros para lo cual usamos comandos de la forma: $ *ls .txt Que lista todos los ficheros acabados en .txt.
  • representa cero o más caracteres, con lo que *ed encontraría el fichero ed. Otro comodín menos usado es? que sustituye por un sólo carácter, por ejemplo: $ ls carta?.txt Listaría ficheros como carta1.txt, carta2.txt, pero no carta10.txt. El tercer comodín permite indicar un conjunto de caracteres que son válidos para hacer la sustitución, p.e. c[ao]sa encontraría el fichero casa y cosa, pero no cesa. Además podemos indicar un conjunto de caracteres ASCII consecutivos, por ejemplo [a-z] serían todas las letras minúsculas, [!0-9]

serían todos los caracteres ASCII excepto los dígitos, y [a-zA-Z0-9] serían todas las letras mayúsculas, minúsculas y los dígitos. La razón por la que este comodín no ha sido tan usado como se esperaba es que expande por un, y sólo un dígito, por ejemplo programa.[co] encontraría programa.c y programa.o, pero no programa.cpp. Es importante tener en cuenta que los comandos cuando se ejecutan no ven los comodines sino el resultado de la expansión. Por ejemplo si ejecutamos el comando: $ cp g /tmp* g* se expande por todos los ficheros que cumplen el patrón, y esto es lo que se pasa al comando cp, pero si no existiera ningún fichero cuyo nombre cumpliese el patrón g, este valor no se expande sino que se pasa tal cual al comando, y éste será el que fallará: $ cp g /tmp/ cp: g*: No such file or directory Es decir, como podríamos pensar, al fallar no se pasa una lista vacía al comando. Piense por un momento lo que ocurriría con algunos comandos si se hubiese diseñado así. Este funcionamiento es ligeramente distinto al de tcsh, donde si no se expande el comodín no se ejecuta el comando, en Bash se ejecuta el comando aunque luego éste produzca un error.

2.2. El comodín tilde

El comodín tilde ~ se usa para referirse al directorio home de los usuarios (/Users en Mac OS X o /home en la mayoría de las máquinas UNIX), por ejemplo si usamos ~carol/carta.txt nos lo expande por /Users/carol/carta.txt. Además podemos usar el comodín tilde para referirnos a nuestro propio directorio, 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 hubiera puesto (hubiera puesto ~carta.txt), me habría expandido por la ruta /Users/carta.txt, y si no existe un usuario con el nombre carta.txt hubiera producido un error indicando que no existe el directorio.

cl[e-i]ve.h Por último comentar que la llave debe contener al menos dos cadenas, sino no se realiza la expansión: $ echo ca{a}sa ca{a}sa De nuevo este comportamiento difiere con el de tcsh, donde la expansión se realiza 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 opción ext_glob de Bash (véase el apartado 3 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 de pattern-list *( pattern-list ) Cero o más ocurrencias de pattern-list +( pattern-list ) Una o más ocurrencias de pattern-list @( pattern-list ) Exactamente uno de los patrones de la lista !( pattern-list ) Cualquier cosa excepto uno de los patrones de la lista pattern-list recibe uno o más patrones separados por |. Cada patrón de esta lista puede contener comodines, por ejemplo +([0-9]) busca cadenas formadas por uno o más dígitos. En el apartado 2.1 vimos que un problema que presentaba el comodín? era que carta?.txt listaría ficheros como carta1.txt, carta2.txt, pero no carta10.txt. Esto lo podemos solucionar con el comodín extendido +( pattern-list ) de la forma: carta+([0..9]).txt

También vimos en el apartado 2.1 que .[cho] encontraría los ficheros con extensión .c, .o y .h, pero no había forma de encontrar los .cpp ya que el corchete sólo aceptaba un carácter. Ahora podemos usar el comodín @( pattern-list ) para indicar la lista de extensiones a aceptar. Por ejemplo .@(c|o|h|cpp) encontraría correctamente estos ficheros: $ ls .@(c|o|h|cpp) clave.cpp clave.h También hubiera sido equivalente usar @(.c|.o|.h|.cpp) ya que los patrones pueden estar anidados. Si lo que hubiéramos querido es encontrar todos los ficheros excepto los .gif, los .jpg y los .html podríamos haber usado el patrón !(.html|gif|jpg). Sin embargo, en este caso no podríamos haber usado *.!(html|gif|jpg) Un último ejemplo, si queremos borrar todos los ficheros excepto los que empiezan por vt seguido por uno o más dígitos podemos usar el comando: $ rm !(vt+([0-9]))

4. Redirecciones y pipes

4.1. Operadores de redirección

UNIX está basado en una idea muy simple pero muy útil: Tratar todos las entrada y salidas como streams (flujos) de bytes. Cada programa va a tener asociadas siempre una entrada estándar (por defecto el teclado), una salida estándar (por defecto la consola), y una salida de errores estándar (por defecto también la consola). Si queremos, podemos cambiar la entrada estándar para que el programa reciba datos de un fichero usando el operador de redirección <. Por ejemplo el comando cat, si no recibe argumentos, lee del teclado por la entrada estándar y lo pasa a la salida estándar: $ cat Esto es una linea acabada en intro Esto es una linea acabada en intro ^D Podemos indicar el final de un stream desde el teclado con la combinación de teclas Ctrl+D como se muestra en el ejemplo. Podemos cambiar la entrada estándar de cat para que lea de un fichero con: $ cat < clave.h #ifndef CLAVE_H_ ····· En el caso concreto del comando cat, también puede recibir como argumento el nombre del fichero a pasar a la salida estándar, con lo que en el caso del comando cat nos podríamos haber ahorrado el operador <: $ cat clave.h #ifndef CLAVE_H_ ····· UNIX dispone de un gran número de comandos que leen de la entrada estándar, realizan una operación con el texto, y escriben en la salida estándar (o en la salida de errores si se produce un error): cat, grep, soft, cut, sed, tr,... El operador de redirección de salida > permite cambiar la salida estándar de un comando, por ejemplo:

$ date > ahora Envía el día y hora actuales al fichero ahora. También podemos cambiar a la vez la entrada y salida estándar de un programa usando ambos operadores de redirección. Por ejemplo: $ cat < ficheroa > ficherob También podemos cambiar la salida de errores estándar con el operador de redirección 2>. Por ejemplo: $ cat < ficheroa > ficherob 2>errores Copia el ficheroa en el ficherob, y si se produce algún error lo escribe en el fichero errores. Si no queremos sobrescribir un fichero de salida sino añadir el contenido al final podemos usar el operador de redirección >> para la salida estándar o 2>> para los errores estándar. Por ejemplo: $ ls p >>ficheros 2>>errores* Añadiría los ficheros que lista ls al fichero ficheros, y si se produjesen errores los añadiría al fichero errores. El operador de redirección 2>> es especialmente útil para almacenar los conocidos logs de errores. Muchas veces no se quiere que un programa muestre mensajes en la consola del usuario, en este caso es muy común redirigir su salida estándar y salida de errores estándar al fichero /dev/null: $ *gcc .cpp > /dev/null 2> /dev/null

4.2. Pipes

Es posible redirigir la salida estándar de un programa a la entrada estándar de otro usando el operador | (pipeline). more es uno de los comandos típicos que lo usan. Este comando lo que hace es recoger la entrada estándar y irla mostrando poco a poco (página a página), luego si por ejemplo tenemos un directorio con muchos ficheros podemos hacer: $ ls - la | more y se irán mostrando página a página los ficheros.

5. Ejecución secuencial y concurrente de

comandos

Podemos ejecutar un comando que tarde mucho en ejecutarse y dejarlo ejecutando en background precediéndolo por &. Por ejemplo para compilar un conjunto de ficheros fuente de un programa C++ podemos hacer: $ *gcc .cpp & Aunque el proceso se sigue ejecutando en background, los mensajes que produce salen en la consola impidiéndonos trabajan cómodamente. 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 estándar, con lo que seguiría saliendo en consola. Podríamos evitarlo redirigiendo también la salida de errores estándar, pero quizá sea mejor que se nos informase del error. 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, podríamos querer compilar el comando clave para luego ejecutarlo: $ gcc clave.cpp - o clave ; clave Este comando primero compila el programa, y cuando acaba de compilarlo lo ejecuta.

6. Caracteres especiales y entrecomillado

Los caracteres <, >, |, & *,? , ~, [, ], {, } son ejemplos de caracteres especiales para Bash que ya hemos visto. La Tabla 1. 2 muestra todos los caracteres especiales de Bash. Más adelante veremos otros comandos tienen sus propios caracteres especiales, como puedan ser los comandos que usan expresiones regulares o los operadores de manejo de cadenas. Carácter Descripción ~ (^) Directorio home ` (^) Sustitución de comando

(^) Comentario

$ (^) Variable & (^) Proceso en background ; (^) Separador de comandos

  • (^) Comodín 0 a n caracteres ? (^) Comodín de un sólo carácter / (^) Separador de directorios ( (^) Empezar un subshell ) (^) Terminar un subshell \ (^) Carácter de escape < (^) Redirigir la entrada > (^) Redirigir la salida | (^) Pipe [ (^) Empieza conjunto de caracteres comodín ] (^) Acaba conjunto de caracteres comodín { (^) Empieza un bloque de comando } (^) Acaba un bloque de comando ' (^) Entrecomillado fuerte " (^) Entrecomillado débil ! (^) No lógico de código de terminación Tabla 1. 2 : Caracteres especiales de Bash

6.1. Entrecomillado

Aunque los caracteres especiales son muy útiles para Bash, a veces queremos usar un carácter especial literalmente, es decir sin su significado especial, en este caso necesitamos entrecomillarlo (quoting). Por ejemplo si queremos escribir en consola el mensaje: 2*3>5 es una expresión cierta, podemos usar el comando echo así: