Introducción - Estructura - Historia - Acceso - Filesystem - Shell - Comandos

Como señalé en el capítulo 1, el Shell es un programa interpretador de comandos que lee cada comando que ingresa el usuario y dispone lo necesario para que se ejecuten. En este capítulo daré a conocer ciertos aspectos del Shell estándar del sistema, como el inicio, las órdenes de entrada, los canales de entrada y salida, etc.

Shell de presentación

Es el shell que se inicia automáticamente cuando el usuario se presenta al sistema. Por defecto es sh (o jsh si se utiliza control de trabajo).

Cuando este Shell se inicia, busca un archivo llamado .profile en su directorio de presentación. Este archivo es un guión de shell que contiene órdenes que generalmente se usan para personalizar el entorno.

Por ejemplo, este .profile especifica que el tipo de terminal es vt100, cambia la petición de orden a "SVR4> ", y ejecuta el programa who cada vez que el usuario se presenta:

 TERM=vt100
 export TERM
 PS1="SVR4> "
 export PS1
 who

Luego de ejecutar el .profile, visualiza la petición de orden que informa al usuario que está listo para recibir una orden (Este es el indicador que fue cambiado por el .profile:

SVR4> _

Para terminar el shell de presentación y despedirse del sistema, se presiona Control-D o se utiliza la orden exit.

$ exit_

Órdenes de entrada

Una línea de orden es la que uno ingresa cuando el Unix muestra la petición de orden. Cada línea termina al presionar [Return], que es la tecla que le avisa al Shell que la orden está ingresada. Luego el Unix ejecuta la orden y vuelve a visualizar la petición de orden, comenzando de nuevo.

Los argumentos de la línea de orden son opciones que modifican lo que hace la orden, y cómo lo hace, y la información de entrada que necesita. A menudo la línea de orden contiene argumentos o símbolos que son realmente instrucciones para el Shell. Por ejemplo, el símbolo > (mayor que) redirige la salida de una orden hacia un archivo.

El signo ; (punto y coma) es un separador que permite poner más de una orden en una línea. Por ejemplo, esta línea de entrada pide al Shell la ejecución de la orden date, seguida de la orden ls, como si se hubieran escrito en dos líneas distintas:

$ date ; ls

Se pueden abreviar los nombres de los archivos en los argumentos mediante el uso de patrones especiales o comodines (wildcards) para especificar uno o más archivos sin tener que escribir los nombres completos; también para especificar de una sola vez un conjunto de archivos o buscar un archivo cuando se conoce sólo parte de su nombre.

El Shell sh proporciona tres "comodines", los que son: * , ? y [...]. El asterisco identifica cualquier cadena de caracteres, incluyendo cadenas vacías. Por ejemplo:

*datos
Identifica cualquier nombre terminado en datos, como muchosdatos, f.datos, etc.
cat*
Identifica cualquier nombre que comience con cat, como cat, catita, catalina, etc.
*and*
Identifica cualquier nombre que contenga la cadena and en cualquier lugar, como comando, mandarin, andres, etc.

El signo ? identifica a cualquier caracter simple. Ejemplo:

memo?
Identifica a memo1, memol y memos, pero no a memo, memo.1 ni a memoria.

Los corchetes [...] definen clases de caracteres simples que identifican a cualquier caracter perteneciente a la clase. Ejemplo:

[GJH]erman
Identifica a German, Jerman y Herman, pero no a german, pues se reconoce distinción entre mayúsculas y minúsculas.

Se puede indicar un rango de caracteres entre corchetes con un guión (-). Ejemplos:

Pin[1-3]
Identifica a Pin1, a Pin2 y a Pin3, pero no a Pin8.
A[-_.]A
Identifica a A-A, A_A y A.A; si se desea incluir un guión entre los caracteres identificables, debe ser el primer caracter de la clase.

Como dije anteriormente, * identifica a cualquier caracter o cadena de caracteres. Pero hay una excepción: los archivos cuyos nombres empiezan con un punto (llamados "archivos ocultos" en Unix), sólo serán identificados si el punto inicial es especificado dentro del patrón. Por ejemplo, *profile identificará a profile y old.profile, pero no a .profile.

Algunos shells modernos, particularmente bash del proyecto GNU, incorporan un nuevo comodín, los paréntesis de llave {...}, que se usan para identificar subconjuntos de caracteres. Por ejemplo:

Chi{le,na}
Identifica a Chile y a China, pero no a Chilena.
direc{tor,tora,ción}_nac
Identifica a director_nac, directora_nac y dirección_nac.

Entrada y salida estándar

La mayoría de las órdenes UNIX aceptan entrada textual desde teclado y/o envían información textual a la pantalla. Sin embargo, a veces el usuario necesita que la información que envía un programa sea guardada en un archivo o traspasada a otro programa para proceso adicional.

En Unix, se puede redireccionar la entrada y salida estándar de las órdenes de acuerdo a lo que indique el usuario. Para ello, luego de especificar la orden con todos sus argumentos, se utilizan los símbolos <, >, >> y |, los que se conocen como operadores de redirección del Shell.

Entrada Estándar                  Salida Estándar
   ARCHIVO -----.             .----> ARCHIVO
   TECLADO -----+--> ORDEN ---+----> PANTALLA
   ORDEN   -----'             '----> ORDEN

El operador > le dice al Shell que envíe la salida del comando a la izquierda del símbolo, hacia el archivo especificado a la derecha del mismo. Por ejemplo:

$ ls > Temp

Genera un archivo nuevo llamado Temp, cuyo contenido es la información arrojada por ls. Si existe un archivo con ese nombre en el directorio actual, será borrado y reemplazado por la salida de la orden.

El operador >> se usa en forma similar a >. La diferencia es que >> añade datos al archivo sin borrarlo, añadiendo la salida al final del archivo o creando uno nuevo si no existe.

El operador < dice al Shell que use el archivo siguiente como entrada de una orden. Por ejemplo:

$ cat < file

Ejecuta la orden cat leyendo datos del archivo file.

Algunas órdenes, en particular muchas órdenes de manejo de archivos, permiten especificar también un archivo de entrada como argumento. Por ejemplo, las órdenes

$ cat < file

y

$ cat file

Procesan el mismo archivo, y producen el mismo resultado, aunque el mecanismo es distinto: En el primer caso, el shell pone a file como entrada de cat, y en el segundo caso, la orden cat abre a file y lee de él su entrada.

El operador | dice al shell que tome la salida estándar de una orden y la use como entrada de otra órden.

$ who|grep lgm
Ejecuta who y envía su resultado (una lista de los usuarios que están
trabajando en el sistema) a la entrada estándar de grep, la que la procesa
(busca en ella la cadena "lgm").

Además de la entrada y salida estándar, existe otro canal lógico que sirve para que el comando se comunique con el usuario. Se trata de la salida de diagnóstico o error estándar, que indica resultados y mensajes de error de manera independiente de la salida estándar. Por ejemplo, la orden cat imprime el siguiente mensaje cuando no se encuentra un archivo:

$ cat nofile
cat: nofile not found.

El error estándar, al igual que la salida estándar, se puede redirigir a un archivo. Esto se logra con el operador 2> . Por ejemplo:

$ cat nofile > temp 2> errores

Envía la salida al archivo temp y cualquier mensaje de error al archivo errores.

Para añadir un error estándar a un archivo, se utiliza el operador 2>> . Ejemplo:

$ lp archivo.ps 2>> mensajes_impresion

Variables del Shell

En el Shell se pueden definir variables, que se utilizan para contener información utilizada por el sistema y para uso del usuario. Pueden servir para personalizar la información relativa a directorios y archivos usados por programas, etc.

Las siguientes son algunas variables del Shell, que tienen un propósito especial para él. Éstas son:

HOME
Contiene el camino absoluto del directorio de presentación del usuario. Es definida automáticamente y es utilizada por el comando cd para determinar el directorio al cual debe cambiar cuando no se especifica ninguno.
PATH
Contiene la lista de directorios en que el Shell busca un programa cuando se teclea una orden. Cada directorio se separa por dos puntos (:). Un campo vacío en esta cadena (con dos puntos, pero sin nombre de directorio), significa buscar en el directorio actual.
Ejemplo: PATH=/bin:/usr/bin:/usr/local/bin:/usr/games:/home/lgm/bin:
Indica que cuando se introduzca una orden, se debe buscar primero en el directorio /bin, luego en /usr/bin, luego en /usr/local/bin, luego en /usr/games, luego en /home/lgm/bin, y finalmente en el directorio actual.
CDPATH
También contiene una lista de directorios separados por dos puntos (:), en este caso los que busca el Shell para encontrar un subdirectorio al cual cambiar cuando se da la orden cd.
LOGNAME
Es el nombre de presentación del usuario y es fijado automáticamente por el sistema.
PS1 y PS2
Definen los signos de petición de orden primaria y secundaria respectivamente. Por defecto sus valores respectivos son $ y >. Algunos shells permiten agregar secuencias de escape para insertar valores tales como fecha actual, nombre del directorio actual, etc.
MAIL
Es el lugar donde se coloca el nuevo correo para los usuarios, y donde los programas de correo revisarán por correo local.
MAILFILE
Utilizado por mailx, una orden del UNIX de AT&T, para especificar un archivo de correo.
SHELL
Es el nombre del programa de Shell, y es utilizado por ciertos programas para salir temporalmente al Shell. Nótese que el usuario no puede elegir qué shell desea usar al inicio de su sesión simplemente cambiando esta variable; para ello debe usar el comando chsh.
TERM
Contiene información sobre el tipo de terminal en uso, y lo utilizan muchos programas para efectuar en forma correcta sus funciones de entrada y salida.

Para obtener el valor de una variable del Shell, debe anteponerse al nombre de la variable un signo $. Para mostrar su valor en la pantalla, puede utilizar la orden echo, que imprime un mensaje en la pantalla. Por ejemplo:

$ echo PATH
PATH
$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/usr/games:/home/lgm/bin:

La primera orden muestra el mensaje "PATH" en la pantalla, mientras que la segunda muestra el valor de la variable PATH.

La orden set se utiliza para mostrar todas las variables actuales del Shell y sus valores. Una salida de la orden set en un sistema Linux como el que estoy usando puede verse similar a esto:

$ set
 BASH=/bin/bash
 BASH_ENV=/home/lgm/.bashrc
 BASH_VERSION=1.14.7(1)
 CHARSET=latin1
 COLUMNS=80
 DICTIONARY=espanol
 EUID=500
 HISTFILE=/home/lgm/.bash_history
 HISTFILESIZE=1000
 HISTSIZE=1000
 HOME=/home/lgm
 HOSTNAME=mutrun.lgm.cl
 HOSTTYPE=i386
 IFS= 	
 
 INPUTRC=/etc/inputrc
 LANG=es_ES
 LESSOPEN=|/usr/bin/lesspipe.sh %s
 LINES=25
 LOGNAME=lgm
 MAIL=/var/spool/mail/lgm
 MAILCHECK=60
 OLDPWD=/home/lgm
 OPTERR=1
 OPTIND=1
 OSTYPE=Linux
 PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/lgm/bin
 PPID=5965
 PS1=\h:\w> 
 PS2=> 
 PS4=+ 
 PWD=/home/lgm/escritos/unix
 SHELL=/bin/bash
 SHLVL=1
 SYSFONT=lat1-16
 TERM=linux
 UID=500
 USER=lgm
 USERNAME=
 _=set

Una variable se define o se cambia de valor escribiendo su nombre, seguido de un signo = y su valor. Ejemplo:

$ TERM=vt100

Si el valor tiene espacios o caracteres especiales, se debe escribir entre comillas. Ejemplo:

$ PS1="Reboot a las 17 hrs >"
Reboot a las 17 hrs >_

Variables de entorno

Son las que el shell pone a disposición de los comandos llamados por él. Este conjunto de variables y sus valores se llama entorno, e incluye las variables fijadas por el sistema. La orden env visualiza las variables de entorno. Estas son las variables que se han exportado del shell al entorno completo, y pueden ser utilizadas por comandos y otros programas, como el editor vi.

No todas las variables están exportadas al entorno del usuario. Cualquier variable que el usuario cambie o defina no está inmediatamente exportada. Para ponerla a disposición de otros programas, se usa la orden export:

$ MAILCHECK=40
$ export MAILCHECK

Sustitución de órdenes

Se puede sustituir la salida de una orden en la línea de orden, de la misma forma que se sustituyen las variables. Esto se logra con las comillas invertidas, `...`, colocando entre ellas a la orden cuya salida se quiere sustituir en la línea de orden.

Por ejemplo, si el archivo names contiene los nombres de camino de tres archivos de texto:

$ cat names
/home/lgm/escritos/manual.txt
/sites/lgm/prc/files
/tmp/correo_abril

La orden siguiente editaría cada uno de estos archivos:

$ vi `cat names`

Esta orden equivale a:

$ vi /home/lgm/escritos/manual.txt /sites/lgm/prc/files /tmp/correo_abril

Otros caracteres especiales del Shell

Existe una lista de otros caracteres que tienen significado especial para el Shell. Estos son:

&
Ejecuta una orden o grupo de órdenes en modo subordinado. Esto permite la ejecución de dos o más trabajos en forma simultánea. Ejemplo:
$ troff Tarch > Tarchout &
[1] 2547
$ _

Formatea el archivo Tarch en modo subordinado. Si esta orden se hubiese ejecutado en modo directo, el Shell esperaría que la orden terminara de ejecutarse antes de mostrar la petición de orden. En modo subordinado, se muestra el número de trabajo de la orden ingresada y el número de proceso dentro del sistema, e inmediatamente se muestra la petición de orden, pues el Shell está listo para recibir una nueva orden, pero el programa queda, mientras tanto, ejecutándose.

Cuando el programa termina de ejecutarse, el Shell avisa con el siguiente mensaje antes de pedir nuevamente la petición de orden:

$ echo Hola
Hola
[2]-  Done    troff Tarch > Tarchout
\
Es un símbolo que elimina el significado del siguiente caracter especial. Ejemplo:
$ echo $HOME
/home/lgm
$ echo \$HOME
$HOME
' "
Las comillas simples y dobles hacen que el shell no interprete el texto entre comillas y hace que los caracteres especiales entre ellas no tengan su significado especial. La diferencia entre ' y " es que cualquier caracter $ " ' o \ que haya entre comillas dobles sí será interpretado como caracter especial. Ejemplos:
$ cinco_mil=5000
$ echo 'casa = $cinco_mil'
casa = $cinco_mil
$ echo "casa = $cinco_mil"
casa = 5000

Copyright © 2007 - Luis Alejandro González Miranda - locoluis en gmail