next up previous
Next: Escribiendo Scripts Up: Lo común a todos Previous: Seleccionando un Shell

Los metacaracteres

En todos los shells existe una serie de caracteres que nos sirven para construir comandos y scripts 5.1. En la siguiente tabla se describen:


\begin{displaymath}\vline
\begin{tabular}{\vert r\vert l\vert}
\hline
{\bf Símb...
...ilita el eco de metacaracteres. \\
\hline
\end{tabular}\vline
\end{displaymath}

A continuación mostramos ejemplos de cada uno de los metacaracteres:

1.
Redirigiendo la salida estándar sobre un fichero texto:



width 3pt
width .3pt415ptgogh: > ls
bin/              doc@              un_fichero_ASCII
carta             f@
gogh: > ls > 1 (redirigimos la salida estándar sobre el fichero 1)
gogh: > cat 1      
1
bin/
carta
doc@
f@
un_fichero_ASCII
gogh: >
width .3pt
depth .3pt width -3pt

2.
Añadiendo la salida estándar a un fichero texto ya creado:



width 3pt
width .3pt415ptgogh: > echo eso es todo >> 1 (añadimos una nueva línea al fichero 1)
gogh: > cat 1
1
bin/
carta
doc@
f@
un_fichero_ASCII
eso es todo
gogh: >
width .3pt
depth .3pt width -3pt

3.
Redirigiendo la entrada estándar desde un fichero ya creado hacia un comando que la usa:



width 3pt
width .3pt415ptgogh: > sort < 1 (redirigimos la entrada para ordenar el fichero 1)
1
bin/
carta
doc@
eso es todo
f@
un_fichero_ASCII
gogh: >
width .3pt
depth .3pt width -3pt

4.
Usando el metacarácter de redirección de la salida de un script sobre un comando:



width 3pt
width .3pt415ptgogh: > cat birth-day (script que envía una felicitación de cumpleaños)
# Esto es una línea con comentarios
# $1 es un argumento del script
# FinDelScript es una etiqueta que marca la parte del script
# que va a ser redireccionada sobre la utilidad de mail
mail $1 << FinDelScript (redirigimos la salida del script sobre el mail)
Muy buenas $1, (nombre del usuario que felicitamos)

   ! ! !   F E L I Z   C U M P L E A  N O S   ! ! !
   Hasta pronto.
   - $USER (usuario que envía la felicitación)
FinDelScript (palabra que marca el final del script que es redirigido)
echo Felicitación de cumpleaños enviada a $1
gogh: > birth-day vi (nos enviamos a nosotros una felicitación)
Felicitación de cumpleaños enviada a vi
gogh: > mail (comprobamos si tenemos correo)
Mail version 5.3 2/18/88.  Type ? for help.
"/var/spool/mail/vi": 1 message 1 new (vemos que si, nos hemos autoescrito)
>N  1 vi                    Mon Apr 24 00:29  21/352
& (pulsamos la tecla return )
Message 1: (vemos nuestra felicitación)
From vi Mon Apr 24 00:29:23 1995
To: vi
Muy buenas vi,
   ! ! !   F E L I Z   C U M P L E A  N O S   ! ! !
   Hasta pronto.
   - vi

& quit (salimos de la utilidad de correo)
Held 1 message in /var/spool/mail/vi
gogh: >
width .3pt
depth .3pt width -3pt

5.
Usando los wildcards para sustituir nombres de ficheros:



width 3pt
width .3pt415ptgogh: /pru> ls -FR (recursivamente listamos el directorio actual)
a.c    b.c    cc.c   dir1/  dir2/
dir1:
d.c  e.e
dir2:
f.d  g.c
gogh: /pru> ls *.c (cualquier número de caracteres seguidos por ".c")
a.c   b.c   cc.c
gogh: /pru> ls ?.c (un solo carácter seguido de ".c")
a.c  b.c
gogh: /pru> ls [ac]* (cualquiera que comience por ''a'' o ''c'')
a.c   cc.c
gogh: /pru> ls [A-Za-z]* (aquellos que comiencen por letras)
a.c   b.c   cc.c
dir1:
d.c  e.e
dir2:
f.d  g.c
gogh: /pru> ls dir*/*.c (de los directorios que empiezan por "dir", los que acaban en ".c")
dir1/d.c  dir2/g.c
gogh: /pru> ls */*.c (de cualquier directorio, los que acaban ebn ".c")
dir1/d.c  dir2/g.c
gogh: /pru> ls *2/?.? ?.? (de los directorios acabados en "2", ficheros con dos caracteres)
a.c       b.c       dir2/f.d  dir2/g.c (separados por un punto, ídem en el directorio actual)
gogh: /pru>
width .3pt
depth .3pt width -3pt

6.
Como ejemplo de la sustitución de comandos ver el apartado del comando echo . Este ejemplo nos sirve también para comprobar el uso del símbolo $.

7.
Encauzando las salidas y las entradas estándar: el pipeline (o uso de pipes) es una filosofía muy utilizada en UNIX, que consiste en dividir grandes problemas en subtareas que pueden ser resueltas por pequeños procesos, que a su vez pueden ser reutilizados en la resolución de otras tareas.



width 3pt
width .3pt415ptgogh: > ls
1                 birth-day*        doc@              pru/
bin/              carta             f@                un_fichero_ASCII
gogh: > ls | wc -w (contando el número de entradas en el directorio)
8
gogh: > cat /etc/passwd | awk -F: '{print $1}' | sort
adm
bin (lista ordenada de los usuarios del sistema)
daemon
ftp
games
halt
lp
mail
man
news
operator
postmaster
root
shutdown
sync
uucp
vi
gogh: >
width .3pt
depth .3pt width -3pt

8.
Separando comandos mediante el carácter ; :



width 3pt
width .3pt415ptgogh: > ls;date
1                 birth-day*        doc@              pru/
bin/              carta             f@                un_fichero_ASCII
Mon Apr 24 01:24:10 GMT 1995
gogh: >
width .3pt
depth .3pt width -3pt

9.
Ejecución condicional: todo proceso en UNIX termina con un valor de salida. Por convención, una finalización con éxito representa un retorno del valor 0 y un error devuelve un valor distinto de 0 (normalmente 1, esto puede ser programado cuando se construye el programa ejecutable):



width 3pt
width .3pt415ptiron% cat hola.c
#include <stdio.h>
main() {
        printf("Hola !\n'');
}
iron% cc hola.c && a.out (compilamos y ejecutamos si hemos compilado con éxito.)
Hola !
iron% cc Hola.c || echo Ese programa no existe
cpp: Hola.c: No such file or directory
Ese programa no existe
iron%
width .3pt
depth .3pt width -3pt

10.
Agrupando comandos:



width 3pt
width .3pt415ptgogh: > (pwd; date; ls) > 1
gogh: > cat 1
/usr/users/v (pwd)
Mon Apr 24 02:03:28 GMT 1995 (date)
1 (ls)
bin/
birth-day*
carta
doc@
f@
pru/
un_fichero_ASCII
gogh: >
width .3pt
depth .3pt width -3pt

11.
Utilizando el background: esta es la forma más primitiva y a la vez actual de utilizar la multitarea en UNIX. Es muy útil, pues permite realizar dos o más tareas al mismo tiempo (en pseudo-concurrencia si sólo disponemos de un procesador o en concurrencia real si se dipone de más de una CPU):



width 3pt
width .3pt415ptgogh: > find . -name a.c -print | mail vi & (buscamos el fichero a.c)
[1] 84 85
gogh: > cc hola.c (y mientras compilamos el fichero hola.c)
[1]    Done                   find . -name a.c -print | mail vi
gogh: > mail (leo mi mail)
Mail version 5.3 2/18/88.  Type ? for help.
"/var/spool/mail/vi": 2 messages 1 new
.   1 vi                    Mon Apr 24 00:29  22/363 (un mail antiguo)
>N  2 vi                    Mon Apr 24 16:06  14/264 (y el nuevo)
& (pulsamos return o 2 )
Message 2:
From vi Mon Apr 24 16:06:05 1995
To: vi
./pru/a.c (localización del fichero a.c)
& q (salimos de la utilidad de mail)
Held 2 messages in /var/spool/mail/vi
gogh: >
width .3pt
depth .3pt width -3pt

Este ejemplo puede no ser demasiado claro en en sentido de que es necesario que el comando find debe finalizar no más tarde que el comando mail, pero tiene que tenerse en cuenta que ambos comandos se ejecutaron simultaneamente. Esta característica si se aprecia cuando necesitamos realizar dos tareas diferentes sobre un volumen de datos muy grande y elazamos ambas tareas mediante pipes. Notaremos que en cuanto la primera tarea ha generado datos de salida la tarea que espera comienza a actuar sobre estos datos, mucho antes de que todo el volumen de datos haya atravesado la primera tarea. Esto ayuda a optimizar el uso de los recursos del sistema, entre ellos el más importante: la CPU.

12.
Escribir comandos largos es tan fácil como esto:



width 3pt
width .3pt415ptgogh: > echo hola \
? caracola
hola caracola
gogh: >
width .3pt
depth .3pt width -3pt

13.
Y por último, podemos trabajar con los metacaracteres:



width 3pt
width .3pt415ptgogh: > echo también es posible escribir metacaracteres '&'
también es posible escribir metacaracteres &
gogh: >
width .3pt
depth .3pt width -3pt

next up previous
Next: Escribiendo Scripts Up: Lo común a todos Previous: Seleccionando un Shell
Vicente González Ruiz
1998-07-13