Una Introducción al Shell Unix
Prólogo
He aquà el tratado introductorio la Shell de la Séptima Edición de UNIX, escrita por su propio autor, S. Bourne. Su clásico no sólo es interesante desde el punto de vista histórico, sino que por derecho propio guarda relevancia como buen tutorial general para el intérprete de comandos al que inspiró, el Bourne Again Shell del proyecto GNU.
La presente edición en forma de documento HTML es la "revisada para 4.3BSD por Mark Seiden", lo que permite datarlo al menos para finales de 1986. Sin embargo, ante diferencias lógicas de ambos sistemas - directorios de spool de correo, llamadas de sistema divergentes (BSD incorporó nuevas) - decidà proceder con arreglo al original. Debe tenerse en cuenta además ciertos detalles menores de la interfaz de terminal que el paso del tiempo hizo alterar (la tecla Retroceder o DEL usualmente ya no opera como caracter INTERRUPCIÓN, etc). Este inconveniente se replica en gran parte de la documentación original de UNIX producida en Murray Hill (incluso el excelente The Unix Programming Environment de Kernighan y Pike). La fuente parcial puede encontrarse AquÃ
Una Introducción al Shell UNIX
S. R. Bourne
Abstract
La shell es un lenguaje de programación de comandos que provee una interfaz de operación para el sistema operativo UNIX. Sus funcionalidades incluyen primitivas de control de flujo, pasaje de parámetros, sustitución de variables y cadenas. Es posible utilizar contrucciones de programación tales como while, if, then, else, case y for. Es posible establecer comunicación bidireccional entre la shell y los comandos. Pueden pasarse parámetros de valor de cadena a un comando, tÃpicamente nombres de fichero o flags. En los comandos puede usarse un código de retorno para determinar un control de flujo, y la salida estándar de un comando puede utilizarse como entrada de la shell.La shell puede modificar el ambiente el cual corre el comando. La entrada puede modificar el ambiente en el cual corren los comandos. La entrada y salida pueden redirigirse a ficheros, y pueden invocarse procesos comunicados a través de "tuberÃas". Los comandos se localizan buscando en directorios situados en el sistema de archivaje según una secuencia que puede redefinir el usuario. Los comandos pueden ser leÃdos desde el terminal o desde un fichero que permite utilizar guiones de shell capaces de ser almacenados para uso posterior.
UNIX es una marca registrada de AT&T Bell Laboratories en los EE.UU. y otros paÃses.
1.0 Introducción
La shell es tanto un lenguaje de órdenes como un lenguaje de programación, que provee una interfaz para la operación del sistema operativo UNIX. Este memorando describe a la shell UNIX a través de ejemplos. La primer sección abarca la mayorÃa de los requerimientos diarios de los operadores de un terminal. Al estudiar dicha sección es ventajoso contar con cierta familiaridad con UNIX (consultar, por ejemplo, "UNIX para principiantes"). La Sección 2 describe aquellas caracterÃsticas de la shell concebidas principalmente para su utilización en procedimientos de interpretación de comandos. Entre estas se incluyen las primitivas de control de flujo y las variables de valor de cadenas provistas por la shell. Será de gran ayuda contar con conocimientos de programación durante el estudio de esta sección. La última sección describe las caracterÃsticas más avanzadas de la shell. Las referencias del tipo "ver tuberÃas (2)" describen a una sección del Manual de UNIX.1.1 comandos Simples
Los comandos simples consisten en una o más palabras separadas por caracter de espacio en blanco. La primer palabra es el nombre del comando a ejecutar; cualquier palabra restante a continuación cobra el significado de argumento del comando. Por ejemplo,es un comando que presenta los nombres de aquellos usuarios con sesión en el sistema de cómputo UNIX. El comandowho
presenta un listado de los ficheros que se encuentran en el directorio actual. El argumento dado por la forma -l solicita a ls la presentación de información adicional de status, tamaño y la fecha de creación de cada fichero del listado.ls -l
1.2 comandos en Segundo Plano
Usualmente, para proceder a la ejecución de un comando, la shell genera un proceso de cómputo nuevo y aguarda por su finalización. El comando puede ejecutarse sin aguardar esta finalización. Por ejemplo,ordena al compilador C proceder a la compilación del fichero pgm.c. El sÃmbolo de & especificado al final consiste en un operador que instruye a la shell no aguardar la finalización de la orden. Para ayudar en la gestión de los proceso, la shell reporta el número de proceso correspondiente una vez que éste ha sido generado. Es posible obtener un listado de los procesos actualmente activos en el sistema utilizando el comando ps.cc pgm.c &
1.3 Redirecciionado de Entrada/Salida
La mayorÃa de los comandos producen como salida un resultado en la salida estándar, que - inicialmente - está conectada al terminal. Esta salida puede ser enviada a un fichero, por ejemplo, escribiendo:La notación >fichero es interpretada por la shell, y no es interpretada como un argumento a ls. En caso que fichero no exista, la shell lo crearÃa; caso contrario los contenidos originales de fichero son reemplazados con la salida proveniente de ls. Es posible agregar la salida a una previamente existente en un fichero, utilizando la notación:ls -l >fichero
En este caso, de no existir fichero también es creado.ls -l >>fichero
Un comando puede recibir entrada estándar desde un fichero en lugar de hacerlo desde el terminal. Al escribir, por ejemplo:
El comando wc lee su entrada estándar - en este caso redirigida desde fichero - y presenta el número de cantidad de lÃneas, palabras y caracteres encontradas. Si sólo se requiere el número de lÃneas, entonces puede argumentarse tal solicitudwc <fichero
wc -l <fichero
1.4 TuberÃas y filtros
Es posible conectar la salida estándar de un comando a la entrada estándar de otro utilizando el operador de "caño", denotado por el sÃmbolo |, tal como en la orden:Dos comandos asà conectados constituyen una tuberÃa y el efecto general es el mismo que ordenarls -l | wc
excepto que no se intermedia fichero alguno. En lugar de utilizarlos, ambos procesos resultan conectados por un caño (ver pipe (2)), lo que amerita su ejecución en paralelo.ls -l >fichero; wc <fichero
Las tuberÃas son unidireccionales y la sincronización se logra deteniendo a wc cuando no hay nada que leer, y deteniendo a ls cuando la tuberÃa está llena.
Se conoce como filtro a un comando que lee su entrada estándar, la transforma de alguna manera, e presenta el resultado como salida. Uno de tales filtros, grep, escoge como su entrada aquellas lÃneas que contienen alguna cadena determinada. Por ejemplo,
presenta aquellas lÃneas de la salida de ls que contienen la cadena reporte (de existir). Otro filtro útil es sort. Por ejemplo,ls | grep reporte
presenta un listado de los usuarios con sesión en la máquina ordenado alfabéticamente.who | sort
Es posible que una cañerÃa conste de más de dos comandos, por ejemplo:
presenta el número del conteo de nombres de fichero del directorio actual los cuales contienen la cadena reporte.ls | grep reporte | wc -l
1.5 Generación de nombre de fichero
Muchos comandos aceptan nombres de fichero como su argumento. Por ejemplo:presenta información relacionada al fichero main.c.ls -l main.c
La shell provee un mecanismo para generar una lista de nombres de ficheros que coincidan con un determinado patrón. Por ejemplo,
como argumentos de ls, genera una lista de todos aquellos nombres de ficheros en el directorio actual que finalicen en .c. El caracter * es un patrón de coincidencia que analiza coincidencias con cualquier cadena, incluyendo la cadena nula. En general los patrones se especifican de la siguiente manera:ls -l *.c
- *
- Hace coincidir cualquier cadena de caracteres, incluyendo la cadena nula.
- ?
- hace coincidir cualquier caracter simple.
- [...]
- Hace coincidir cualquiera de los caracteres encorchetados. De indicarse un par de caracteres separados por un signo "-", coincidirán cualquier caracter que léxica/alfabéticamente se encuentre entre dicho par.
coincide todos los nombres en el directorio actual que comiencen con las letras desde la a a la z. En tanto que,[a-z]*
coincide todos los nombres en el directorio /usr/pedro/test que consistan en un único caracter. De no hallarse un nombre de fichero coincidente con el patrón dado, entonces el patrón es pasado, sin alteración alguna, en forma de argumento./usr/pedro/test/?
Este mecanismo resulta útil tanto para ahorrar tiempo de mecanografiado, como para seleccionar nombres según un patrón determinado. También puede ser útil para encontrar ficheros. Por ejemplo:
busca y presenta los nombres de todos los ficheros core en subdirectorios de /usr/pedro. (echo es un comando estándar de UNIX que presenta sus argumentos separados por espacios). Esta última funcionalidad puede resultar costosa, ya que requiere analizar todos los subdirectorios de /usr/pedro.echo /usr/pedro/*/core
Existe una excepción para las reglas generales de patrones. El caracter `.' al comienzo de un nombre de fichero debe coincidir explÃcitamente. Por lo tanto:
dará como eco todos los nombres de fichero en el directorio actual que no comiencen con `.', en tanto que:echo *
dará como eco de todos los nombres de ficheros que comiencen con `.'. Esto evita hacer coincidir (sin advertirlos) los nombres `.' y `..', que significan "el directorio actual" y "el directorio padre" respectivamente. (Tenga presente que ls suprime presentar información de los ficheros `.' y `..'.)echo .*
1.6 Citado
Se conoce como meta-caracteres aquellos caracteres que tienen un significancia especial para la shell, tales como < > * ? | &,. El Apéndice B ofrece una lista completa de metacaracteres. Cualquier caracter precedido por una barra invertida \ resulta citado, perdiendo dicho significado especial (si lo tuviese). La \ resulta anulado de modo queproducirá el eco de un ? único, yecho \?
dará eco de una única \. Se ignorará la secuencia \newline para permitir que cadenas largas continúen a través de más de una lÃnea.echo \\
El meta-caracter \ resulta conveniente para citar caracteres únicos. Al existir más de un caracter que requiera ser citado, el mecanismo anteriormete decripto puede considerarse torpe y propenso al error. Esa posible entonces citar una cadena de caracteres cerrándolas entre apóstrofos, lo que es más simple. Por ejemplo:
dará como ecoecho xx'****'xx
No es necesario que la cadena citada contenga una cita simple, sino que incluso si contiene caracteres de nueva lÃnea, estos serÃan preservados. Este mecanismo de citado resulta el más simple, y se lo recomienda para el uso casual.xx****xx
También está disponible Un tercer mecanismo de citado que emplea comillas. Este impide el interpretado de algunos - pero no todos - los meta-caracteres. La discusión de los detalles se retrasará hasta la sección 3.4.
1.7 Prompt
Cuando la shell se usa desde un terminal, presenta una venia antes de leer un comando. Por defecto esta venia consiste en un caracter `$ '. Puede ser cambiada diciendo, por ejemplo:que configura la venia para que sea la cadena siquerido. Si se mecanografÃa una nueva lÃnea y se necesita mayor entrada, entonces la shell dará la venia `> '. A veces esto puede ser provocado por mecanografiar un signo de apóstrofe. Si es inesperado, entonces introducir una interrupción (DEL) retornará al shell para leer otro comando. Esta venia puede cambniarse, diciendo, por ejemplo:PS1=siquerido
PS2=mas
1.8 La shell y login
Siguiendo al login (1) se llama a la shell para leer y ejecutar comandos mecanografiados en el terminal. Si el directorio de login del usuario contiene el fichero .profile entonces asume que este contiene comandos, y resulta intepretado por la shell antes de leer algún comando del terminal.1.9 Resúmen
- ls
- presenta los nombres de los ficheros en el directorio actual.
- ls >fichero
- Coloca la salida de ls en fichero.
- ls | wc -l
- presenta el númereo de ficheros en el directorio actual.
- ls | grep viejo
- presenta aquellos nombres de fichero que contiene la cadena viejo.
- ls | grep reporte | wc -l
- presenta el número de ficheros cuyo nombre contiene la candena reporte.
- cc pgm.c &
- Ejecuta cc en segundo plano.
2.0 Guiones de shell
La shell puede ser utilizada para leer y ejecutar mandatos contenidos en un fichero. Por ejemplo:ordena a la shell leer los comandos contenidas en fichero. Tal fichero se conoce como un procedimiento de comandos o un guion de shell. (N.d.T: Se ha preferido el uso actual de guión o shell script, de la traducción oficial de "procedimiento de comandos"). Junto con su llamada a ejecución pueden proporcionarse argumentos, y ser referidos a fichero usando los parámetros posicionales $1, $2, .... Por ejemplo: si el fichero wg contiene:sh fichero [ argumentos ... ]
entonceswho | grep $1
es equivalente ash wg pedro
Los fiheros de UNIX tienen tres atributos independientes, read, write y execute. El comando de UNIX chmod (1) puede ser usado para ordenar que un fichero sea ejecutable. Por ejemplo:who | grep pedro
asegura que el fichero wg cuente con atributo de ejecución. Tras ello, la ordenchmod +x wg
es equivalente al mandatowg pedro
Esto permite utilizar los guiones de shell y los programas binarios de forma intercambiable. En cualquiera de los casos, se crea un nuevo proceso para ejecutar la orden.sh wg pedro
Asà como es posible proveer nombres para los parámetros posicionales, es posible utiliazr número de parámetros posicional durante la llamada, siguiendo una sintaxis $#. El nombre del fichero en ejecución es disponible como $0.
Se puede usar un parámetro de shell especial $* para sustituir todos los parámetros posicionales exceptuando $0. Un uso tÃpico de esto es proveer algunos argumentos por defecto, como en
que simplemente añade algunos argumentos a aquellos ya dados.nroff -T450 -ms $*
2.1 Flujo de Control - for
Uno de los usos frecuentes de los guiones de shell es conformar un bucle a través de los argumentos ($1, $2, ...), ordenando la ejecución de órdenes una vez para cada argumento. Un ejemplo de un guión tal es tel, que busca el fichero /usr/lib/telnos que contienen lÃneas de la formaEl texto de tel es... pedro mh0123 beto mh0789 ...
El comandofor i do grep $i /usr/lib/telnos; done
presenta aquellas lÃneas en /usr/lib/telnos que contienen la cadena pedro.tel pedro
presenta aquellas lÃneas que contienen pedro seguidas por aquellas para beto.tel pedro beto
La notación de bucle for es reconocida por la shell y tiene la sintaxis general
Una lista-de-comandos es una secuencia de uno o más comandos simples separados o terminados por una lÃnea nueva o un punto y coma. Además, las palabras reservadas como do y done sólo son reconocidas si son seguidas por una nueva lÃnea o un punto y coma. nombre es una variable de shell que está establecida a las palabras w1 w2 ... en turno a cada vez que lista-de-comandos siguiendo a do es ejecutada. Si in w1 w2 ... está omitido, entonces el bucle se ejecuta una vez para cada parámetro posicional; esto es, se asume in $*.for nombre in w1 w2 ... do lista-de-comandos done
Otro ejemplo del uso del bucle for es el comando create cuyo texto es:
El comandofor i do >$i; done
asegura que dos ficheros vacÃos alfa y beta existan y estén vacÃos. La notación >fichero puede usarse por sà misma para crear o eliminar el contenido de un fichero. Tenga también presente que se requiere un punto y coma ";" (o un caracter de nueva lÃnea) antes del done.create alfa beta
2.2 Flujo de control - case
Se provee un arbolado de rumbo mútiple para la notación case. Por ejemplo,es un comando de agregado. Cuando se lo llama con un argumento como encase $# in 1) cat >>$1 ;; 2) cat >>$2 <$1 ;; *) echo \'uso: append [ desde ] hasta\' ;; esac
$# es la cadena 1 y la entrada estándar es copiada al final de fichero usando el comando cat.append fichero
agrega los contenidos de fichero1 al fichero2. Si el número de los argumentos dados a append es diferente a 1 o 2, entonces se presenta un mensaje indicando la forma debida de uso.append fichero1 fichero2
La sintaxis general del comando case es
La shell intenta coincidir palabra con cada patrón en el orden en el cual aparecen los patrones. Si se encuentra una coincidencia, la lista-de-comandos asociada es ejecutada, y la órden del case se completa. Ya que * es el patrón que coincide con cualquier cadena, puede utilizarse para definir el case por defecto.case palabra in patrón) lista-de-comandos;; ... esac
Debe advertir que no se realizan revisiones que aseguren que sólo un patrón coincide con el argumento del case. La primera coincidencia encontrada define el conjunto de comandos a ejecutar. En el ejemplo que se ofrece a continuación, las órdenes que siguen al segundo * no resultarán ejecutadas jamás.
Otro ejemplo del uso de la construcción case consiste en la distinción entre las formas de argumentos posibles. El siguiente ejemplo es un fragmento de un comando cc.case $# in *) ... ;; *) ... ;; esac
A fin de permitir que el mismo comando resulte asociado con más de un patrón, el comando case provee el uso de patrones alternativos, separados por un |. Por ejemplo,for i do case $i in -[ocs]) ... ;; -*) echo \'flag desconocido $i\' ;; *.c) /lib/c0 $i ... ;; *) echo \'argumento inesperado $i\' ;; esac done
es equivalente acase $i in -x|-y) ... esac
Las convenciones de citado usuales aplican, de modo quecase $i in -[xy]) ... esac
coincidirá el caracter ?.case $i in \?) ...
2.3 Documentos Here
El guión de shell tel de la sección 2.1 usa el fichero /usr/lib/telnos para suplir los datos a grep. Una alternativa a esto es incluir tales datos dentro del guión de shell, en forma de un documento here, tal comoEn tal ejemplo, la shell interpreta las lÃneas entre <<! y ! como la entrada estándar para grep. La cadena ! es abitraria, el documento resulta terminado por una lÃnea consistente en la cadena que sigue a <<.for i do grep $i <<! ... pedro mh0123 beto mh0789 ... ! done
Los parámetros resultan sustituidos en el documento antes de hacerlos disponibles a grep, según se ilustra en el siguiente guión de shell denominado edg.
La llamadaed $3 <<% g/$1/s//$2/g w %
por tanto equivalente al comandoedg cadena1 cadena2 fichero
cuyo mandato es sustituir todas las iteraciones de cadena1 en fichero por cadena2. La sustitución puede prevenirse usando "\" para citar el caracter especial $, como si se hicieseed fichero <<% g/cadena1/s//cadena2/g w %
(Esta versión de edg es equivalente a la primera, excepto que ed presentará un ? si no existen ocurrencia de la cadena $1.) La sustutución dentro de un documento here puede ser impedida enteramente citando la cadena de terminación, por ejemplo,ed $3 <<+ 1,\$s/$1/$2/g w +
El documento es presentado sin modificación a grep. Esta última forma es más eficiente, si la sustitución de parámetros no es requerida en un documento here.grep $i <<\# ... #
2.4 Variables de Shell
La shell provee variables cuyo valor está formado por cadenas. Los nombres de las variables comienzan con una letra y consisten de letras, dÃgitos y guiones bajos "_". Las variables pueden ser valores dados por escrito, por ejemploque asigna valores a las variables user, box y acct. Una variable puede establecerse a una cadena nula diciendo, por ejemplo,user=pedro box=m000 acct=mh0000
El valor de la variable se substituye precediendo su nombre con $; por ejemplo:null=
dará como eco pedro.echo $user
Las variables pueden usarse forma interactiva para proveer abreviaturas a las cadenas comunmente usadas. Por ejemplo:
moverá el fichero pgm desde el directorio actual al directorio /usr/pedro/bin. Una notación más general está disponible para la sustitución de parámetro (o variable), como enb=/usr/pedro/bin mv pgm $b
la cual es equivalente aecho ${user}
y es usada cuando el nombre de parámetro es seguido por una letra o dÃgito. Por ejemplo,echo $user
direcciona la salida de ps al fichero /tmp/psa, mientras que,tmp=/tmp/ps ps a >${tmp}a
ordena que el valor de la variable tmpa sea sustituÃdo.ps a >$tmpa
Excepto para $? lo siguiente es configurado inicialmente por la shell. $? es establecido luego de ejecutar cada comando.
- $?
- el estatus de salida (código de retorno) del último comando ejecutado como una cadena decimal. La mayorÃa de los comandos devuelve un estatus de salida cero si se completan exitosamente, de otro modo retornan un status de salida no cero. Se considerarán luego los códigos de valor de retorno bajo los comandos if y while.
- $#
- El número de los parámetros posicionales (en decimal). Usado, por ejemplo, en el comando append para revisar el número de parámetros.
- $$
- El número de procesos de esta shell (en decimal).
Como los números de procesos son únicos entre todos los procesos existentes, esta cadena es frecuentemente usada para generar nombres de fichero temporales únicos. Por ejemplo:
ps a >/tmp/ps$$ ... rm /tmp/ps$$
- $!
- El número de proceso del último proceso ejecutado en segundo plano (en decimal).
- $-
- Las flags del shell actual, tales como -x y -v.
- Cuando es usada interactivamente, la shell busca en el fichero especificado por esta variable antes de proporcionar una Venia. Si el fichero especificado ha sido modificado desde la última vez que fue revisado, la shell presenta el mensaje you have mail antes de hacer la venia aguardadno la siguiente órden. Esta variable tÃpicamente se configura en el fichero .profile situado en el directorio de login del usuario. Por ejemplo:
MAIL=/usr/mail/pedro
- $HOME
- Argumento por defecto para el comando cd. El directorio actual se utiliza para resolver las referencias de nombre de fichero que no comienzan con un /, y se cambia empleando el comando cd. Por ejemplo,
hace que el directorio actual sea /usr/pedro/bin.cd /usr/pedro/bin
presentará en el terminal el fichero wn situado en este directorio actual. El comando cd sin argumentos es equivalente acat wn
Esta variable es establecida también en el perfil de login del usuario.cd $HOME
- $PATH
- Listado de directorios que contienen comandos (la ruta de búsqueda). Toda vez que se ordena la ejecución de un comando a la shell, esta busca un fichero ejecutable respectivo en el listado rutas de búsqueda. Si $PATH no está establecida, entonces por defecto se lo busca en el directorio actual, /bin, y /usr/bin. En caso contrario, $PATH consiste de nombres de directorio separados por un :. Por ejemplo,
especifica al directorio actual (la cadena nula antes del primer :), /usr/pedro/bin, /bin y /usr/bin deberán ser analizados durante la búsqueda, en ese órden. De esta manera, se posibilita a los usuarios individuales distener sus propios comandos "privados" a los que acceden, independientemente del directorio actual. Si el nombre de comando contiene un / entonces esta búsqueda de directoria se ignora; solo se realiza un intento de ejecutar el comando.PATH=:/usr/pedro/bin:/bin:/usr/bin
- $PS1
- La primera cadena de venia de shell, por defecto, `$ '.
- $PS2
- La venia de shell cuando se necesita una entrada adicional, por defecto, `> '.
- $IFS
- El conjunto de caracteres utilizados por blank interpretation (ver sección 3.4).
2.5 El comando test
El comando test, aunque no es parte de la shell, está pensado para ser usado por programas de la shell. Por ejemplo,devuelve un status de salida cero si fichero existe, o un status de salida no cero si se produce lo contrario. En general test evalúa un predicado y devuelve el resultado en forma de su status de salida. Aquà se proporcionan ciertos argumentos frecuentemente utilizados de test; consulte test (1) por una especificación completa.test -f fichero
- test s
- true si el argumento s no es una cadena nula
- test -f fichero
- true si fichero existe
- test -r fichero
- true si fichero tiene permiso de lectura
- test -w fichero
- true si fichero tiene permiso de escritura
- test -d fichero
- true si fichero es un directorio
2.6 Control de Flujo - while
Las acciones del bucle for y el arbolado case son determinadas según los datos disponibles a la shell. Un bucle while o until y un arbolado if then else también son provistos a aquellas acciones determinadas por el estatus de salida devuelto por los comandos. Un bucle while tiene la sintaxis generalEl valor probado por el comando while es el estado de salida del último comando simple que sigue al while. Cada iteración del bucle lista-de-comandos1 se ejecuta; si se retorna un valor de estado de salida cero, entonces se ejecuta lista-de-comandos2; de lo contrario, el bucle finaliza. Por ejemplo,while lista-de-comandos1 do lista-de-comandos2 done
es equivalente awhile test $1 do ... shift done
shift es un comando de la shell que renombra los parámetros posicionales $2, $3, ... como $1, $2, ... y descarta $1.for i do ... done
Otro tipo de uso para el bucle while/until es aguardar hasta que ocurra algún evento externo y luego correr algunos comandos. En un bucle until la condición de terminación es invertida. Por ejemplo,
hará bucle hasta que exista fichero. Cada iteración del bucle aguardará durante cinco minutos antes de intentar nuevamente. (Presumiblemente, otro proceso crea eventualmente el fichero)until test -f fichero do sleep 300; done commands
2.7 Flujo de Control - if
También está disponible un arbolado condicional general de la sintaxisque evalúa el valor devuelto por el último comando simple que sigue al if.if lista-de-comandos then lista-de-comandos else lista-de-comandos fi
El comando if puede usarse en conjunción con el comando test para evaluar la existencia de un fichero como en
Un ejemplo del uso de las construcciones if, case y for se da en la sección 2.10.if test -f fichero then process fichero else do something else fi
Un comando de evaluación múltiple ifde la sintaxis
puede escribirse usando la extensión de la notación if,if ... then ... else if ... then ... else if ... ... fi fi fi
El siguiente ejemplo es el comando touch que cambia el horario de "última modificación" para una lista de ficheros. El comando puede ser usado en conjunto con make (1) para forzar una recompilación de una lista de ficheros.if ... then ... elif ... then ... elif ... ... fi
El flag -c se utiliza en este comando para forzar la creación de ficheros subsecuentes si no existiesen. En caso contrario - si el fichero no existe - se presenta un mensaje de error. La variable de shell flag resulta establecida a alguna cadena no nula si se encuentra el argumento -c. Los comandosflag= for i do case $i in -c) flag=N ;; *) if test -f $i then ln $i basura$$; rm basura$$ elif test $flag then echo fichero \'$i\' no existe else >$i fi esac done
crean un enlace al fichero y luego lo remueve, provocando por lo tanto la actualización del horario de última modifición.ln ...; rm ...
La secuencia
puede ser escritaif comando1 then comando2 fi
Conversamente,comando1 && comando2
ejecuta comando2 sólo si comando1 falla. En cada caso, el valor devuelto es aquél del último comando simple ejecutado.comando1 || comando2
2.8 Agrupamiento de comandos
Los comandos pueden ser agrupados de dos maneras,y{ lista-de-comandos ; }
En la primera, simplemente es ejecutada lista-de-comandos. La segunda manera ejecuta lista-de-comandos en forma de proceso separado. Por ejemplo,( lista-de-comandos )
ejecuta rm basura en el directorio x sin proceder a cambiar el directorio actual del shell que lo ha invocado.(cd x; rm basura )
Los comandos
surten el mismo efecto, pero dejan al shell invocante en el directorio x.cd x; rm basura
2.9 Depurando guiones de shell
La shell provee dos mecanismos de trazabilidad para asistir al depurado de los guiones de shell. El primero de ellos se invoca dentro del guion, como en:v ofrece un resultado de respuesta verbosa y provoca la devolución de las lÃneas del guión de shell, impresas en la medida que son leÃdas. Esto resulta útil para asistir en la tarea de aislar errores sintácticos. Puede ser invocárselo sin alterar el guión de shell, indicandoset -v
en donde script es el nombre del guión de shell. Esta flag puede ser utilizada en conjunto con el flag -n que impide la ejecución de comandos subsecuentes (tenga presente que indicar set -n en el terminal, hará que este deje de responder hasta que produzca el ingreso de un caracter EOF (N.d.T.: EOF: Fin de Fichero, se logra con Ctrl+d).sh -v script ...
El comando
producirá una traza de ejecución. Tras la acción de sustitución de parámetros, se presenta cada órden en la medida que resulta ejecutada (es posible evaluarlas en el terminal para considerar su resultado). Ambos flags pueden desactivarse indicandoset -x
y la configuración actual de las flags de la shell están disponibles como $-.set -
2.10 El comando man
El siguiente es el comando man que se usa para presentar secciones del manual de UNIX. Se lo llama, por ejemplo, conse presentará la primer sección del manual para sh. Como no se especificó sección, se usa la sección 1. El segundo ejemplo usará la opción de código de fotocomposición (ordenada con la opción -t) para ed. La última orden se encarga de presentar la página de manual de fork a partir de la sección 2.$ man sh $ man -t ed $ man 2 fork
Figura 1. Una versión del comando mancd /usr/man : 'colon is the comment command' : 'default is nroff ($N), section 1 ($s)' N=n s=1 for i do case $i in [1-9]*) s=$i ;; -t) N=t ;; -n) N=n ;; -*) echo unknown flag \'$i\' ;; *) if test -f man$s/$i.$s then ${N}roff man0/${N}aa man$s/$i.$s else : 'look through all manual sections' found=no for j in 1 2 3 4 5 6 7 8 9 do if test -f man$j/$i.$j then man $j $i found=yes fi done case $found in no) echo \'$i: manual page not found\' esac fi esac done
3.0 Parámetros de palabra clave
Las variables de shell pueden ser valores dados por asignación o por invocación durante el tiempo de ejecución de un guión de shell. Un argumento de guión de shell con la forma nombre=valor que procede al nombre de comando, provoca que valor resulte asignado a nombre antes que comience la ejecución del guión. El valor de nombre en la shell invocante no resulta afectado. Por ejemplo,ejecutará comando con el usuario configurado para ser pedro. El flag -k provoca que los argumentos de la forma nombre=valor resulten interpretados en esta forma en cualquier lugar de la lÃsta de argumentos. Tales nombres a veces son conocidos como parámetros de palabras clave. De restar alguno de los argumentos, se hacen disponibles como parámetros posicionales $1, $2, ....usuario=pedro comando
Desde dentro de un guión de shell puede utilizarse el comando set para especificar parámetros posicionales también. Por ejemplo,
establecerá $1 como primer nombre de fichero en el directorio actual, $2 como el siguiente nombre de fichero, y asà sucesivamente. Tenga presente que el primer argumento "-" asegura el tratamiento correcto cuando el primer nombre de fichero comienza con un caracter -.set - *
3.1 Transmisión de parámetros
Al invocar un guión de shell, pueden suplirse tanto los parámetros posicionales como las palabras clave en dicha invocación. Los parámetros de palabra clave también pueden implicitarse a un guión de shell, especificando de forma adelantada la exportación de tales parámetros. Por ejemplo,demarca las variables user y box para su exportación. Al invocar un guión de shell, se realizan copias de todas las variables exportadas para su uso dentro del guión invocado. La modificación de tales variables dentro del guión no afecta los valores en la shell que lo ha invocado. Generalmente es verdadero que un guión de shell no modifica el estado de la shell que lo ha invocado sin la solicitud explÃcita por parte del shell invocante (los descriptores de fichero compartido son una excepción a esta regla).export user box
Aquellos nombres cuyo valor se encuentran concebidos para permanecer constantes pueden ser declarados como de sólo lectura. La sintaxis de esta operación es la misma que aquella utilizada para el comando export,
De aquà en mas, intentos subsecuentes de establecer variables de sólo lectura son ilegales.readonly nombre ...
3.2 Sustitución de parámetros
Si un parámetro de shell no resulta establecido, entonces es sustituÃdo por una cadena nula. Por ejemplo, si la varibale d no está configuradaoecho $d
presenta un eco nulo. Puede darse una cadena por defecto como enecho ${d}
que dará como eco el valor de la variable d si es establecida, y `.' si es lo contrario. La cadena por defecto es evaluada utilizando las convenciones de citado usuales, de modo queecho ${d-.}
dará como eco * si la variable d no está establecida. De forma similarecho ${d-'*'}
dará como eco el valor de de d si está establecida y el valor de $1 (si lo tiene) en caso contrario. Una variable puede ser asignada a un valor por defecto utilizando la notaciónecho ${d-$1}
que sustituye la misma cadena comoecho ${d=.}
y si d no hubiese sido establecida previamente, entonces será establecida como la cadena `.'. (la notación ${...=...} no está disponible para los parámetros posicionales).echo ${d-.}
Si no hay un valor por defecto sensible, entonces la notación
dará eco el valor de la variable d si cuenta con uno, caso contrario mensaje resulta impreso por la shell, y la ejecución del guión de shell se abandona. Si mensaje está ausente, entonces se presenta un mensaje estándar. Un guión de shell que requiera que se establezcan algunos parámetros puede iniciar de la siguiente manera:echo ${d?message}
Los dos puntos (:) es un comando incorporado en la shell y no hace nada una vez que sus argumentos han sido evaluados. Si alguna de las variables user, acct or bin no han sido establecidas, entonces la shell abandona la ejecución del procedimiento.: ${user?} ${acct?} ${bin?} ...
3.3 Sustitución de comandos
La salida estándar de un comando puede ser sustituÃda de manera similar a los parámetros. El comando pwd presenta en su salida estándar el nombre del directorio actual. Por ejemplo, si el directorio actual es /usr/pedro/bin entonces el comandoes equivalente ad=`pwd`
La cadena entera entre acentos graves (`...`) se toma como el comando a ejecutar, y es reemplazdo con la salida del comando. El comando es escrito utilizando las convenciones de citado convencionales, con la excepción que un ` debe ser escapado, usando un \. Por ejemplo,d=/usr/pedro/bin
es equivalente als `echo "$1"`
La sustitución de comandos ocurre en todos aquellos contextos donde ocurre también la sustitución de parámetros (incuyendo documentos here) y el tratamiento del texto resultante es el mismo en ambos casos). Este mecanismo permite utilizar los comandos de procesamiento de cadenas dentro de los guiones de shell. Un ejemplo de tales comandos lo constituye basename, el cual remueve de una cadena un sufijo especificado. Por ejemplo:ls $1
presenta la cadena main. Su uso se ilustra por el siguiente fragmento como un comando cc.basename main.c .c
que establece B como la parte de $A con el sufijo .c removido.case $A in ... *.c) B=`basename $A .c` ... esac
He aquà algunos ejemplos compuestos
- · for i in `ls -t`; do ...
- donde la varible i resulta establecida para los nombres de fichero en órden temporal, los más recientes primero.
- · set `date`; echo $6 $2 $3, $4
- presenta, por ejemplo, 1977 Nov 1, 23:59:59
3.4 Evaluación y citado
La shell es un procesador de macros que provee sustitución de parámetros, sustitución de comandos, y generación de nombres de fichero para los argumentos de comandos. Esta sección discute el orden en el cual dichas evaluaciones ocurren, y los efectos de los variados mecanismos de citado.Los comandos son analizados inicialmente de acuerdo a la gramática dada en el Apéndice A. Antes de que un comando se ejecute, ocurren las siguientes sustiotuciones.
- sustitución de parámetros, ej. $USER
- sustitución de comandos, ej `pwd`
- Solo se produce una evaluación, de modo que si - por ejemplo - el valor asignado a la variable X es la cadena $y, entonces
dará como eco $y.echo $X
- interpretación de caracteres en blanco
- Siguiendo a las sustituciones mencionadas, los caracteres resultantes resultan divididos en palabras no en blanco (interpretación
de caracteres en blanco). En este cometido se interpreta en blanco a los caracters de la cadena $IFS. Por defecto, esta cadena consiste en un caracter en blanco, un tabulador, y una nueva lÃnea. La cadena nula no es considerada como una palabra, a no ser de que esté citada. Por ejemplo:
pasará a la cadena nula como el primer argumento de echo, como enecho ''
llama a echo sin argumentos si la variable null no está establecida, o está establecida a una cadena nula.echo $null
- generación de nombre de fichero
- Cada palabra es luego analizada en busca de los caracteres de patrón de ficheros *, ? y [...] y resulta generada una lista alfabética de los nombres de ficheros para reemplazar la palabra. Cada uno de tales nombres de ficheros es un argumento separado.
Junto con estos mecanismos de citados ya descriptos que utilizan \ y '...', se provee un tercer mecanismo de citado, que en el cual se utiliza entrecomillado "...". Dentro de las comillas se producen la sustitución de parámetros y de comandos, pero se produce la generación de nombre de ficheros ni la interpretación en blanco. Los caracteres a continuación guardan un significado especial en el entrecomillado, y pueden ser citados usando \.
- $
- sustitución de parámetros
- `
- sustitución de comandos
- "
- finaliza la cadena citada
- \
- cita los caracteres especiales $ ` " \
pasa el valor de la variable x como un argumento simple de echo. De forma similar,echo "$x"
pasa los parámetros posicionales como un argumento simple; equivale aecho "$*"
La notación $@ es similar a $*, a excepción que esté citada:echo "$1 $2 ..."
pasa los parámetros posicionales (sin evaluarlos) a echo, y es equivalente aecho "$@"
La siguiente tabla indica los metacaracteres de la shell que resultan evaluados para cada uno de los mecanismos de citado.echo "$1" "$2" ...
En los casos donde se requiere más de una evaluación de una cadena, se puede usar el comando incorporado de la shell eval. Por ejemplo, si la variable X tiene el valor $y, y si y tiene el valor pqr, entoncesFigura 2. Mecanismos de citadoMeta-caracter \ $ * ` " ' ' n n n n n t ` y n n t n n " y y n y t n t terminador y interpretado n nointerpretado
da como eco la cadena pqr.eval echo $X
Por lo general el comando eval evalúa sus argumentos de la misma manera en que lo hacen todos los comandos, y trata el resultado como una entrada al shell. La entrada es leÃda y el/los comando/s resultantes son ejecutados. Por ejemplo
equivale awg=\'eval who|grep\' $wg pedro
En dicho ejemplo, se requiere usar eval ya que sucedida la sustitución efectuada, no existe intepretación de meta-caracteres, tal como en |.who|grep pedro
3.5 Manejo de Error
El tratamiento de los errores detectados por la shell dependen del tipo de error y si la shell está siendo utilizada según su modalidad interactiva. Una shell interactivca es una donde la entrada y salida se encuentran conectadas a un terminal (como lo determina gtty (2)). Una shell invocada con el flag -i también es interactiva.La ejecución de un comando (ver también 3.7) da fallo por cualquiera de los siguientes motivos:
- La redirección Entrada-Salida ha fallado. Por ejemplo, si un fichero no existe o no puede ser creado.
- El comando en sà no existe o no puede ser ejecutado.
- El comando termina de forma anormal, por ejemplo, con un "error de bus" o "fallo de memoria". Ver Figura 2 abajo por una lista completa de señales de UNIX.
- El comando termina normalmente pero devuelve un estado de salida no cero.
- Errores de sintaxis. Ej, if ... then ... done
- Una señal tal que interrupción. La shell aguarda que el comando actual, si hay alguno, finalice su ejecución y luego o sale o retorna al terminal.
- Fracaso de cualquiera de los comandos incorporados tales como cd.
Aquellas señales marcadas con un asterisco producen un volcado de núcleo si no son atrapadas. Sin embargo, la shell en si misma ignora a quit, la cual es la única señal externa que puede provocar un volcado de núcleo. Las señales en esta lista de interés potencial para los programas de la shell son 1, 2, 3, 14 y 15.Figura 3. Señales de UNIX
- 1
- hangup
- 2
- interrupt
- 3*
- quit
- 4*
- illegal instruction
- 5*
- trace trap
- 6*
- IOT instruction
- 7*
- EMT instruction
- 8*
- floating point exception
- 9
- kill (cannot be caught or ignored)
- 10*
- bus error
- 11*
- segmentation violation
- 12*
- bad argument to system call
- 13
- write on a pipe with no one to read it
- 14
- alarm clock
- 15
- software termination (from kill (1))
3.6 Manejo de Fallas
Los guiones de shell normalmente terminan cuando se recibe una interrupción desde el terminal. El comando trap se utiliza si se requiere alguna limpieza, tal como remover ficheros temporales. Por ejemplo,establece una trampa para la señal 2 (interrupción de terminal), y si esta señal es recibida, ejecutará los comandostrap 'rm /tmp/ps$$; exit' 2
exit es otro comando incorporado de la shell que terminal la ejecución de un guión de shell. El exit se requiere; de lo contrario, luego de que se ha establecido la trampa, la shell continuará ejecutando el procedimiento en el lugar en donde fue interrumpido.rm /tmp/ps$$; exit
Las señales de UNIX pueden ser manejadas en una de tres manearas. Pueden ser ignoradas, en cuyo caso la seña nunca se envÃa al proceso. Pueden se atrsapadas, en cuyo caso el proceso debe decidir qué acción tomar cuando se recibe la señal. Finalmente, pueden ser dejadas para provocar la terminación del proceso sin que este deba tomar mayor acción. Si una señal está siendo ignorada en una etrada al guión de shell, por ejemplo, invocándolo en el segundo plano (ver 3.7), entonces los comandos trap (y la señal) resultan ignoradas.
El uso de trap se ilustra por esta versión modificada del comando touch (Figura 4). La acción de limpieza es remover el fichero basura$$.
El comando trap aparece antes de la creacion del fichero temporal; de otro modo serÃa posible para el proceso, morir sin remover el fichero.Figura 4. El comando touchflag= trap 'rm -f basura$$; exit' 1 2 3 15 for i do case $i in -c) flag=N ;; *) if test -f $i then ln $i basura$$; rm basura$$ elif test $flag then echo fichero \'$i\' no existe else >$i fi esac done
Ya que no hay señal 0 en UNIX, esta es utilizada por la shell para indicar que los comandos sean ejecutados a la salida del guión de shell.
Un procedimiento puede, por si mismo, elegir ignorar señales especificando la cadena nula como el argumento para atrapar. El siguiente fragmento se toma del comando nohup.
que causa que hangup, interrupt, quit, y kill sean ignoradas tanto por el procedimiento y por los comandos invocados.trap '' 1 2 3 15
Las trampas pueden resetearse diciendo
que resetea las trampas para las señales 2 y 3 a sus valores por defecto. Puede obtenerse una listado de los valores actuales de las trampas escribiendotrap 2 3
El procedimiento scan (Figura 5) es un ejemplo del uso de trap donde no hay salida en el comando trap. scan toma cada directorio en el directorio actual, solicita su nombre, y luego ejecuta los comandos mecanografiados en el terminal hasta el final del fichero o se reciba una interrupción. Las interrupciones son ignoradas mientras se ejecutan los comandos solicitados, pero provocan su terminación cuando scan aguarda entrada.trap
read x es un comando incorporado de la shell que lee una lÃnea desde la entrada estándar y coloca el resultado como valor de la variable x. Deuvuelve un status de salida no cero tanto si se recibe una lectura de Fin-de-Fichero o una interrupción.Figura 5. El comando scand=`pwd` for i in * do if test -d $d/$i then cd $d/$i while echo "$i:" trap exit 2 read x do trap : 2; eval $x; done fi done
3.7 Ejecución de comandos
Para ejecutar un comando (otros que los incorporados de la shell), esta inicialmente crea un nuevo proceso utilizando la llamada de sistema fork. El ambiente de ejecución para el comando incluye entrada, salida, y los estados de señales, y se establece en el proceso hijo antes de que sea ejecutado el comando. El comando incorporado de la shell exec se usa en los raros casos donde no se requiere fork, y simplemente reemplaza la shell con un nuevo comando. Por ejemplo, una versión más simple de comando nohup podrÃa serEl trap desactiva las señales especificadas de manera que sean ignoradas por los comandos creados subsecuentementes, y exec reemplaza la shell por el comando especificado.trap \'\' 1 2 3 15 exec $*
La mayorÃa de las maneras de redirección de entrada/salida ya han sido descriptas. La siguiente palabra es sólo sujeta a sustitución de parámetro y comando. No tiene generación de nombre de fichero o interpretación de caracter en blanco, de moque que, por ejemplo
escribirá su salida en un fichero cuyo nombre es *.c. Las especificaciones de entrada/salida son evaluadas de izquierda a derecha en la tal como aparecen en el comando.echo ... >*.c
- > palabra
- La salida estándar (descriptor de fichero 1) es enviado al fichero palabra, el cual es creado si no existe ya.
- >> palabra
- La salida estándar es enviado al fichero palabra. Si el fichero existe, entonces la salida es agregada (buscando su final); de otra forma, se crea el fichero.
- < palabra
- La entrada estándar (descriptor de fichero 0) es tomada desde el fichero palabra.
- << palabra
- La entrada estándar es tomada desde las lÃneas de entrada de la shell que siguen pero que no incluyen una lÃnea consistente solo de palabra. Si palabra es citado, entonces no ocurre interpretación del documento. Si palabra no está citado, entonces ocurren la sustitución de parámetros y comandos y se usa \ para citar los caracteres \ $ ` y el primer caracter de palabra. En el último caso,, se ignora el caracter \newline (refiere a cadenas citadas).
- >& digit
- El descirptor de fichero digit resulta duplicado usando la llamada de sistema dup (2) y el resultado se usa como salida estándar.
- <& digit
- La entrada estándar es duplicada desde el descriptor de fichero digit.
- <&-
- La entrada estándar es cerrada.
- >&-
- La salida estándar es cerrada.
corre un comando con el mensaje de salida (file descriptor 2) dirigido a fichero.... 2>fichero
corre un comando con su salida estándar y un mensaje de salida unificado. (estrictamente hablando, el descriptor de fichero 2 es creado duplicando el descriptor de fichero 1, pero el efecto es usualmente unificar las dos streams)... 2<&1
El ambiente para que un comando que corre en segundo plano como
es modificado en dos maneras. Primeramente, la entrada estándar por defecto para tales comandos es el fichero vacÃo /dev/null. Esto impide dos procesos (la shell y el comando), que están corriendo en paralelo, de intentar leer de la misma entrada. Se producirÃa caos si esto no fuese el caso. Por ejemplo,list *.c | lpr &
permitirÃa tanto al editor y a la shell leer desde la misma entrada al mismo tiempo.ed file &
La otra modificación al ambiente de un comando en segundo plano es desconectar las señales QUIT e INTERRUPT de modo que sean ignoradas por el comando. Esto permite a estas señales ser utilizadas en el terminal sin provicar que el comando en segundo plano termine. Por esta razón la convención UNIX para una señal es que si está establecida en 1 (ignorada), entonces nunca cambia, incluso por un perÃodo corto de tiempo. Tenga presente que el comando trap de la shell no tiene efecto para una señal ignorada.
3.8 Invocando la shell
Las siguientes flags son intepretadas por la shell cuando ésta es invocada. Si el primer caracter del argumento cero es un -, entonces los comandos son leÃdos desde el fichero .profile.- -c string
- Si el flag -c está presente, entonces los comandos son leÃdos desde string.
- -s
- Si el flag -s está presente, o si no quedan argumentos, entonces los comandos son leÃdos desde la entrada estándar. La salida de la shell es escrita al decriptor 2 de fichero.
- -i
- Si el flag -i está presente o si la entrada de la shell y la salida están asociadas al terminal (como lo indica gtty), entonces esta shell es interactiva. En este caso TERMINATE resulta ignorado (de modo que kill 0 no detiene una shell interactiva, e INTERRUPT es atrapado e ignorado (de modo que wait es ininterrumpible. EN todos los casos QUIT es ignorada por la shell.
Reconocimientos
El diseño de la shel se basa en parte en el shell UNIX original, y en la shell de PWB/UNIX. Algunas funcionalides han sido tomadas de ambos. Existen también similitudes con el intéprete de comandos del Sistema de Acceso Múltiple de Cambridge (CMAS) y el CTSS.Quisiera agradecer a Dennis Ritchie y a John Mashey por muchas discusiones durante el diseño de la shell. También estoy agradecido con los miembnros del Centro de Investigación de la Ciencia del Cómputo y con Joe Maranzano por sus comentarios en el borrador de este documento.
Appendix A - Gramática
- item:
- palabra
- input-output
- name = value
- input-output
- simple-command:
- item
- simple-command item
- command:
- simple-command
- ( lista-de-comandos )
- { lista-de-comandos }
- for name do lista-de-comandos done
- for name in palabra ... do lista-de-comandos done
- while lista-de-comandos do lista-de-comandos done
- until lista-de-comandos do lista-de-comandos done
- case palabra in case-part ... esac
- if lista-de-comandos then lista-de-comandos else-part fi
- ( lista-de-comandos )
- pipeline:
- command
- pipeline | command
- andor:
- pipeline
- andor && pipeline
- andor || pipeline
- andor && pipeline
- lista-de-comandos:
- andor
- lista-de-comandos ;
- lista-de-comandos &
- lista-de-comandos ; andor
- lista-de-comandos & andor
- lista-de-comandos ;
- input-output:
- > file
- < file
- >> palabra
- << palabra
- < file
- file:
- palabra
- & digit
- & -
- & digit
- case-part:
- pattern ) lista-de-comandos ;;
- pattern:
- palabra
- pattern | palabra
- else-part:
- elif lista-de-comandos then lista-de-comandos else-part
- else lista-de-comandos
- empty
- else lista-de-comandos
- empty:
- palabra:
- una secuencia de caracteres no nulos
- name:
- a sequence of letters, digits or underscores starting with a letter
- digit:
- 0 1 2 3 4 5 6 7 8 9
Apéndice B - Meta-caracteres y Palabras Reservados
a) sintácticos- |
- sÃmbolo de caño
- &&
- sÃmbolo `andf'
- ||
- sÃmbolo `orf'
- ;
- separador de comandos
- ;;
- delimitador de case
- &
- comandos en segundo plano
- ( )
- agrupamiento de comandos
- <
- redirección de entrada
- <<
- entrada desde un documento here
- >
- creación de salida
- >>
- agregado de salida
- *
- coincide cualquier caracter incluyendo nulos
- ?
- coincide cualquier caracter único
- [...]
- coincide cualquiera de los caracteres entrecorchetados
- ${...}
- substituye variable de la shell
- `...`
- substituye salida de comando
- \
- cita el siguiente caracter
- '...'
- cita los caracteres entre acentos greaves, excepto lo '
- "..."
- cita los caracteres entrecomillados, excepto para $ ` \ "
if then else elif fi case in esac for while until do done { }
Esta es una versión en HTML del tuturial del Shell original de Steve Bourne. Era Eriksson encontró la fuente en http://cm.bell-labs.com/7thEdMan/vol2/shell.bun y generó su propia copia con troff, que luego editó como una versión HTML.
Al descontinuarse la copia localizada en www.iki.fi/era/unix/shell.html, en enero de 2012 realicé una copia local. En e ste documento las referencias a la primer persona fueron reemplazados por el nombre del autor probable de la página, y se ha insertado esta nota en imprenta pequeña. La página original ha sido archivada a través de WebCite como http://www.webcitation.org/64dH90Kic.