1. Objetivos y alcance

1.1. Introducción

El intérprete de comandos o shell es un programa que permite a los usuarios interactuar con el sistema, procesando las órdenes que se le indican. Los comandos invocables desde el shell pueden clasificarse en internos (corresponden en realidad a órdenes interpretadas por el propio shell) y externos (corresponden a ficheros ejecutables externos al shell). Además de comandos, los shells ofrecen otros elementos para mejorar su funcionalidad, tales como variables, funciones o estructuras de control. El conjunto de comandos internos y elementos disponibles, así como su sintaxis, dependerá del shell concreto empleado.

Además de utilizar el shell desde la línea de comandos (basada en el prompt como la indicación del shell para anunciar que espera una orden del usuario), puede emplearse para la interpretación de shell-scripts. Un shell-script o «guión de órdenes» es un fichero de texto que contiene un conjunto de comandos y órdenes interpretables por el shell.

En los S.O.’s Unix existen múltiples implementaciones de shell (en Windows, el equivalente serían los programas «command.com» o «cmd.exe»). Atendiendo al shell del que proceden y a su similitud sintáctica (incluyendo sus comandos internos), los shells de Unix pueden clasificarse en dos grandes familias (existen algunos shell adicionales, de uso residual y dentro de los shells de una misma familia también existen diferencias, pero gran parte de su sintaxis es común):

  1. sh (Bourne Shell): este shell fue usado desde las primeras versiones de Unix (Unix Versión 7). Recibe ese nombre por su desarrollador, Stephen Bourne, de los Laboratorios Bell de AT&T. A raíz de él han surgido múltiples shells, tales como zsh (Z shell), ash (almquist shell), bash (Bourne again shell), dash (Debian almquist shell) o ksh (Korn shell). Por su mayor uso pueden destacarse:

    • bash: fue desarrollado para ser un superconjunto de la funcionalidad del Bourne Shell (en la que incluye funcionalidades de ksh y csh), siendo el intérprete de comandos asignado por defecto a los usuarios en las distribuciones de Linux, por lo que es el shell empleado en la mayoría de las consolas de comandos de Linux. Se caracteriza por una gran funcionalidad adicional a la del Bourne Shell. Como ficheros personales de los usuarios emplea $HOME/.bashrc y .bash_profile.

    • dash (Debian almquist shell), derivado directo de ash, se caracteriza por ser mucho más ligero (depende de menos bibliotecas) y rápido que otros shells, tales como bash, aunque con menos características funcionales. El fichero personal del usuario es $HOME/.profile.

    • ksh (Korn shell): destaca por sus funciones avanzadas para manejar archivos, pudiendo competir con lenguajes de programación especializados tales como awk o perl.

    Bourne Shell ha llegado a convertirse en un estándar de facto de tal modo que todos los sistemas Unix tienen, al menos, una implementación del Bourne Shell (o un shell compatible con él), ubicada en /bin/sh. En el caso concreto de los S.O.’s UNIX Linux, no existe ninguna implementación del Bourne Shell, manteniéndose la entrada /bin/sh (así como su manual man sh) como un enlace simbólico a una implementación de shell compatible. En concreto:

    • En algunos S.O’s Linux se enlaza a /bin/bash.

    • En Debian, desde Debian Lenny «5.0» (en Ubuntu desde la versión 6.10) se enlaza a /bin/dash: de este modo, estas distribuciones pretenden hacer uso de:

      • dash: para los shell scripts empleados en el arranque del sistema (cuyo shebang tradicionalmente siempre ha sido #!/bin/sh), aprovechando la mayor rapidez de este intérprete.

      • bash: en las consolas de comandos y scripts de servicios de los usuarios, de modo que éstos puedan aprovechar la mayor funcionalidad que éste intérprete ofrece.

  2. csh (C shell): caracterizado por presentar una sintaxis muy parecida a la del lenguaje de programación C. Como shell derivados destaca tcsh. Estos shell cuentan con un nivel de uso muy inferior respecto a los de la familia Bourne Shell.

Para intentar homogeneizar esta diversidad de shells, el IEEE definió un estándar de «intérprete de comandos» bajo la especificación POSIX 1003.2 (también recogida como ISO 9945.2). La creación de dicho estándar se basó en la sintaxis que presentaban múltiples shells de la familia Bourne shell (el propio Bourne Shell de Unix Versión 7, implementaciones en UNIX System V y BSD, así como ksh). Esto ha llevado a que la gran mayoría de los shells derivados del Bourne Shell, tales como bash, dash o ksh, den soporte a este estándar POSIX (mientras que los derivados del csh no). En concreto:

  • bash: respeta completamente el estándar POSIX, sobre el que añade un número considerable de extensiones (estructura select, arrays, mayor número de operadores,…).

  • dash: conforme al estándar POSIX IEEE 1003.2, sólo ampliado con algunas extensiones Berkeley. De forma precisa, tal como indica el manual del intérprete dash de su sistema (man dash), la línea de desarrollo de dash pretende que éste satisfaga el estándar POSIX de shells IEEE 1003.2, propósito casi logrado en la actualidad (sólo presenta algunas características faltantes, como la variable $LINENO).

Tareas

  1. Ejecute en su sistema Debian el comando ls -l /bin/sh, y compruebe cómo efectivamente corresponde a un enlace simbólico al intérprete /bin/dash. Asimismo, consulte el manual man sh, comprobando cómo efectivamente obtiene el manual del intérprete dash.

  2. Ejecute los comandos ls -l /bin/dash y ls -l /bin/bash para comprobar cómo efectivamente dispone de dichos shells en su sistema. Puede obtener las versiones instaladas mediante dpkg -s dash y bash –version.

  3. Algunos de los shell-scripts implicados en el proceso de arranque del sistema se encuentran en la carpeta /etc/init.d/. Por ejemplo, mire el contenido del fichero /etc/init.d/rc (encargado del arranque de los servicios) y compruebe cómo la primera línea de dicho script es #!/bin/sh, lo que indica que es interpretado por el shell /bin/dash.

  4. Analice el fichero /etc/passwd y compruebe cómo los usuarios dit y root tienen asignado el shell bash. Abra una consola de comandos con el usuario dit y ejecute el comando ps ax | grep bash, comprobando cómo el proceso del intérprete de comandos usado efectivamente corresponde al shell bash (proceso -bash). Abra una sesión con el usuario root y realice la misma prueba, comprobando cómo igualmente se está usando bash.

1.2. Objetivo

El objetivo es introducir el uso del lenguaje de programación de shell-scripts. Consecuentemente, nos centraremos en la sintaxis de shell propuesta por el estándar POSIX IEEE 1003.2 lo que, conforme a lo antes indicado, se traduce en que todo lo visto aquí podrá ser utilizado en dash, bash y cualquier otro shell que satisfaga dicho estándar. Sobre la base de este documento podrá profundizarse analizando las funcionalidades adicionales añadidas por cada shell, siendo de especial interés, dado su uso, las aportadas por bash.

1.3. Documentación de apoyo

Descarga de los shell-scripts de esta página

Para que no tenga que escribir los scripts que se muestran en esta página a mano, puede descargarse dichos scripts así como la solución a los ejercicios propuestos en el fichero comprimido shellscripts.tar.gz. Descomprímalo con el comando:

tar xfvz ./shellscripts.tar.gz

En el directorio scripts están los ejemplos y en el directorio aplicacion los ejercicios propuestos resueltos.

Descarga en PDF (versión original)

Puede descargarse también la versión original de este documento en formato PDF: FAST_t3-practica.pdf.