You are on page 1of 62

Curso de UNIX

PROLOGO

Este curso ha sido el resultado de algunas de las cosas que he ido aprendiendo
sobre UNIX a lo largo del tiempo. He considerado oportuno comenzar por un curso
básico con el fin de asentar algunas ideas, sobre todo en nuevos usuarios. Quien
sabe, quizás algún día escriba otro más avanzado, o continue ampliando este.

El curso no está pensado como un manual, como podreis observar apenas hablo
de las opciones de los comandos, pues considero que para ello existen manuales
(incluido el manual en línea man) muy buenos (Guias o Manuales de referencia,
de usuario, administración, programación, etc.). Más bien ha sido pensado como
un resumen de tareas habituales, intentando aclarar ideas para cualquier sistema
UNIX.

Como podreis observar a lo largo del presente curso, poco a poco se va


incrementando la dificultad. Lógico y necesario si se quiere prosperar en UNIX.

Durante la fase de pruebas de este curso he recibido algunas peticiones del


mismo en un archivo. Lo podeis encontrar en el area de descarga, aunque
posiblemente no coincida 100% con este, dado que es difícil acordarse de hacer
las modificaciones en los dos sitios cuando andas apurado de tiempo.

Finalmente quiero invitaros a que aporteis ideas, dudas, y por que no, información
para que sea compartida por todos. Quizás así consigamos hacer entre todos un
gran curso.
1. Prólogo al Curso
2. Introducción
3. DOS vs UNIX
4. Estructura de los comandos
5. Lista de Comandos
6. Acceso al sistema
7. Accesos Remotos
8. Variables de Entorno
9. Comillas y más comillas
10. Sistemas de Archivos
11. Procesos
12. Programación de Tareas
13. Tuberias y Redirecciones
14. Expresiones Regulares
15. Estamentos
16. Variables Especiales
17. Shell Scripts
18. Editor vi
19. Sed
20. Awk
21. CGI's
22. Versiones de UNIX. Algunos Enlaces
23. Algunas ideas y ejemplos
INTRODUCCION

Un sistema operativo es la parte software encargada de gestionar los recursos hardware del
sistema y proporciona la base sobre la que se pueden escribir programas de aplicación.
Entre las funciones típicas de un Sistema Operativo, se pueden destacar:

• Gestión de la memoria
• Control de las operaciones de Entrada y Salida
• Tratamiento de Interrupciones
• Control del Sistema
• Establecimiento de prioridades y ejecución de procesos

Como ejemplos de sistemas operativos tenemos DOS, OS2, UNIX, MVS, etc.

El hardware solo se puede controlar a través de ceros y unos. Esto resulta complicado de
manejar para cualquier usuario. Para simplificar estas tareas los ordenadores equipan en
memoria ROM (solo lectura) una serie de instrucciones, de 50 a 300, en ensamblador
(jump, move, add, etc.) que se traducen directamente a código binario.

Los sistemas operativos se pueden construir a partir de instrucciones en ensamblador o a


partir de lenguajes de más alto nivel (como C, Pascal, Basic, etc.). Los lenguajes de alto
nivel no son entendidos por los ordenadores directamente, por lo que hay que compilarlos,
es decir convertirlos a un formato que si pueda ser entendido.

Una de las funciones principales de un sistema operativo es ocultar toda la complejidad


que existe por debajo y proporcionar al programador un conjunto de instrucciones fáciles
de usar.

Por encima del sistema operativo se encuentran aplicaciones y programas, que utilizan los
servicios proporcionados por el sistema operativo. Como ejemplos de aplicaciones nos
encontramos con Windows, PowerPoint, cualquier juego, etc.

Los ordenadores los podemos clasificar según su potencia de menor a mayor en:

• Microordenadores: ordenadores personales, PC, etc.


• Miniordenadores: Ordenadores multiusuario,VAX, 3B2, etc.
• Mainframes: Ordenadores con mayor potencia de procesamiento, IBM 370, etc.
• Superordenadores: Ordenadores de gran potencia utilizados en aplicaciones
científicas, CRAY.
Los comandos se pueden definir como programas que acompañan al sistema operativo sin
formar parte de él, y que están diseñados para trabajar con los demás comandos o con el
kernel (o núcleo) de UNIX.

DOS vs UNIX

DOS es un sistema operativo monoproceso o monotarea, es decir, solo se puede ejecutar


una tarea a la vez, y no comenzará la siguiente hasta que no haya finalizado la que está en
ejecución.

UNIX, por otro lado, es multitarea, permite la ejecución de varios procesos


simultáneamente, sin haber finalizado la ejecución de los mismos. Esto se hace dividiendo
el tiempo en porciones que se asignan a los procesos activos, los cuales se encuentran
almacenados en una cola.

No se debe confundir monoproceso con monoprocesador, pues un sistema monoprocesador


es aquel que solo tiene una CPU o procesador. UNIX puede correr en un PC con una CPU
y permitir la ejecución de varios procesos simultáneamente.

DOS es monousuario, mientras que UNIX es multiusuario, es decir soporta la conexión y


ejecución de programas por parte de varios usuarios.

DOS no se adapta a cada hardware, mientras que UNIX si, aunque será necesario
recompilar el núcleo o Kernel. Esto hace que UNIX sea transportable, que se pueda instalar
en máquinas con hardware muy diferente, con solo unas modificaciones mínimas.

El kernel de UNIX se debe recompilar cada vez que se añada un disco, se modifiquen
parámetros del sistema, se modifiquen los sistemas de archivos de swap o root, o los
dispositivos de consola entre otros. El tiempo necesario para la recompilación dependerá de
la potencia del sistema, de la cantidad de dispositivos que tenga incorporados, etc., pero no
suele ser un tiempo excesivo. En cualquiera de los casos, el sistema operativo se adapta al
hardware existente en la máquina en cada momento. La recompilación puede realizarse
manualmente o automáticamente, dependiendo del desarrollador y de la versión de UNIX
que se tenga.

En DOS en cambio, cada vez que se añade algún hardware nuevo, habrá que instalar los
drivers necesarios para el funcionamiento del dispositivo, como un parche o programa
residente en memoria.

Las máquinas DOS en general son menos potentes que las máquinas UNIX, si bien es
posible encontrar UNIX en máquinas DOS (Linux).
Las máquinas que funcionan con DOS han de ser reiniciadas mucho más frecuentemente
que las máquinas UNIX, si bien es cierto que el tiempo necesario para ello es muy inferior.

En UNIX una unidad lógica o partición puede ocupar varios discos duros o parte de ellos,
mientras que en DOS cada unidad lógica puede ocupar como mucho un disco, y hasta hace
poco tiempo no podía gestionar unidades superiores a 512 MB.

DOS exige, al usuario, unos conocimientos menores que UNIX, así como unas menores
tareas de administración, lo cual lo hace ideal para el público en general. Además dada la
gran aceptación que ha tenido, existe una gran cantidad de programas y utilidades que
hacen aun más sencillo el manejo del ordenador.

ESTRUCTURA DE LOS COMANDOS

Un comando se puede considerar como un programa del sistema operativo que realiza una
acción determinada, es decir, que hace algo. Los comandos pueden llevar opciones,
argumentos o no, y en caso de llevarlas han de ir separadas por espacios o tabuladores.
UNIX es un sistema operativo, a diferencia de DOS, en donde se diferencia entre
mayúsculas y minúsculas, y en donde por tanto habrá que prestar especial cuidado a la hora
de introducir los comandos. Por lo general los comandos suelen escribirse en minúsculas.

Las opciones son modificadores del comando, que pueden hacer que solo presente una
información determinada o que la presente de una u otra forma. El prefijo utilizado en
UNIX para las opciones, generalmente, es el "-", aunque también se pueden encontrar casos
con "+". En DOS el prefijo usado para las opciones es "/". No debe existir espacio entre el
prefijo y la opción. Un prefijo puede ser válido para varias opciones simultáneamente.

Los argumentos indican al comando sobre qué se debe ejecutar la acción, por ejemplo el
nombre de archivo, usuario, etc. Los argumentos no llevan prefijo lo cual sirve para
diferenciarlos de las opciones.

Así pues, la sintaxis general a emplear a la hora de usar un comando será:

Comando ±Opciones Argumentos

En general, se podrán usar varias opciones simultáneamente, al igual que varios


argumentos, si bien será necesario consultar la documentación o la ayuda de cada comando,
para conocer las opciones y argumentos posibles.

Ejemplos:

ls Mostrará los archivos en formato corto (solo el nombre).


ls -l Mostrará los archivos en formato largo (nombre, fecha, atributos, etc.).
ls *.out Mostrará todos los archivos terminados en ".out", en formato corto.
ls -l *.out Mostrará todos los archivos terminados en ".out", en formato largo.

Se pueden ejecutar varios comandos desde una misma línea de comandos, para ello habrá
que separarlos mediante el carácter punto y coma ";".

comando1 argumentos ; comando2 argumentos ; comando3 argumentos

Ejecutará los comandos 1, 2 y 3 secuencialmente, es decir, cuando finalice el comando 1, se


ejecutará el 2, y cuando finalice el 2 se ejecutará el 3. Los resultados de un comando no
tienen por que ser necesarios para el siguiente.

Para que la salida de un comando se pueda utilizar como entrada del siguiente habrá que
utilizar lo que se denomina redirecciones, y merecen un tratamiento diferente.

LISTA DE COMANDOS

A continuacón se muestra una lista con los comandos más habituales en UNIX, así como
una breve descripción de dicho comando. Para ampliar la información de cualquiera de
ellos se recomienda acudir a la ayuda de sistema (man comando) o en cualquier Reference
Manual de UNIX (Manual de Referencia).

at Ejecuta una tarea a la hora programada.


banner Muestra un banner con los argumentos pasados.
bs Calculadora.
cal Muestra un calendario del mes o año indicado.
cancel Cancela trabajos enviados a la impresora.
cat Muestra el contenido de un archivo.
cc Compilador de C bajo UNIX.
cd Cambia de directorio.
clear Limpia la pantalla.
cmp Compara archivos.
compress, pack Comprime un archivo.
cp Copia archivos.
cpio Envía o recupera datos de un archivo cpio (copias de seguridad, etc.).
crontab Programa en el cron de usuario las tareas especificadas.
cut Corta los campos especificados de un archivo.
chgrp Cambia el grupo de un archivo o directorio.
chmod Cambia los permisos de acceso de un archivo o directorio.
chown Cambia el propietario de un archivo o directorio.
cmp Compara dos archivos.
date Muestra la fecha y hora del sistema. Solo root la puede modificar.
df, bdf Muestra información sobre la ocupación de sistemas de archivos.
diff Compara archivos y directorios.
disable Desactiva la impresora, impidiendo la impresión de archivos.
du Muestra la ocupación de un directorio o conjunto de directorios.
echo Muestra por pantalla lo que se indica como argumento.
ed Editor de archivos por líneas.
emacs Editor de textos más potente que vi.
enable Activa la impresora, permite la impresión de archivos.
env Muestra las variables de entorno del usuario.
exit Sale del sistema.
export Exporta el valor de la variable de entorno que se especifique.
file Devuelve el tipo de archivo que es un archivo determinado.
find Busca archivos con unas condiciones determinadas.
Devuelve datos sobre la actividad de los usuarios conectados a un
finger
sistema.
ftp Permite transferir archivos a o desde otros sistemas.
grep, fgrep, egrep Busca una cadena de caracteres dentro de un archivo.
groups Enumera los grupos a los que pertenece un usuario.
head Muestra las primeras líneas de un archivo.
hostname Devuelve o fija el nombre de la máquina.
kill Finaliza la ejecución de un proceso.
ksh, sh, csh Invoca una subshell dentro de la shell actual.
ln Crea un enlace con uno o varios archivos.
lp Envía el contenido de un archivo al spooler de impresión.
lpstat Muestra el estado de las impresoras conectadas al sistema.
ls Lista el contenido de un directorio.
mail, mailx Visualiza y envía correo a otros usuarios.
man Muestra en pantalla la ayuda existente respecto al argumento indicado.
mesg Controla el acceso a la pantalla por parte de otros usuarios.
mkdir Crea un directorio.
more Visualiza el contenido de un archivo por pantallas.
mount Monta un sistema de archivos (lo hace accesible a los usuarios).
mv Mueve archivos de un directorio a otro o los renombra.
newgroup Cambia el grupo actual del usuario, en caso de tener varios.
news Muestra las noticias existentes en el sistema.
Permite reducir la prioridad de un proceso. Solo root puede
nice
incrementarla.
Realiza tareas en background y envía los resultados al archivo
nohup
nohup.out.
passwd Permite modificar la clave o password de un usuario.
paste Junta archivos horizontalmente.
pg Visualiza el contenido de un archivo por pantallas.
pr Formatea un archivo para su posterior impresión.
ps Muestra los procesos activos en el sistema.
pwd Muestra el directorio actual.
rcp Copia archivos desde o hacia otro sistema remoto.
read Lee la entrada que el usuario haga desde el teclado.
rlogin Permite conectarse a otro sistema.
rm Borra un archivo.
rmdir Borra un directorio.
sar Visualiza la ocupación de los procesadores del sistema.
sdiff Compara archivos ASCII, listando las diferencias por columnas.
set Muestra y pone valores a las variables de entorno del usuario.
sort Ordena un archivo.
split Divide un archivo en trozos más pequeños.
stty Establece o visualiza algunas opciones de terminal.
su Permite cambiar la identidad de un usuario a otro.
sync Salva todos los buffers pendientes a disco.
tail Muestra las últimas líneas de un archivo.
Establece una conexión con otro usuario para mantener una
talk
comunicación.
tar Envía o recupera datos de un archivo tar (copias de seguridad, etc.).
tee Dirige la entrada estándar a un archivo y al terminal a la vez.
telnet Permite conectarse a otro sistema.
test Prueba una condición devolviendo true o false.
Muestra en pantalla el tiempo que ha sido necesario para ejecutar un
time
comando.
Modifica la fecha y hora de un archivo. Si no existe lo crea con tamaño
touch
0.
tr Filtro que sirve para intercambiar un carácter por otro.
Visualiza y establece permisos para los archivos y directorios que se
umask
generen.
umount Desmonta un sistema de archivos.
Devuelve información sobre el nombre de la máquina, versión S.O.,
uname
etc.
uncompress,
Descomprime un archivo comprimido.
unpack
users Devuelve los usuarios conectados al sistema.
vi Permite editar archivos.
wait Espera la finalización de tareas en background.
wall Envía un mensaje a todos los usuarios conectados al sistema.
wc Cuenta las palabras, líneas y caracteres de un archivo.
Busca un archivo dentro de los directorios definidos en la variable
whence
PATH.
Localiza un archivo dentro de los directorios incluidos en $PATH y
which
aliases.
who Muestra los usuarios que están conectados al sistema.
write Envía un mensaje a la pantalla del usuario especificado.

ACCESO AL SISTEMA

Para acceder al sistema hay que introducir una identidad de usuario o login, y una clave
secreta o password. El login de usuario es único dentro de un sistema y tiene asociado un
número llamado identidad de usuario, es decir, no pueden existir 2 usuarios con el mismo
login. Por el contrario, dos usuarios diferentes pueden tener la misma clave secreta o
password (por lo general ellos lo ignorarán). Cuando se escribe el login, para acceder a un
sistema, este es visible en la pantalla, en cambio cuando se escribe el password no, o bien
se muestran asteriscos, con el fin de que no pueda ser visualizado por nadie (al mostrar
asteriscos, puede dar pistas sobre el número de caracteres de esta clave, por lo cual no es un
buen método). La clave de un usuario solo podrá ser cambiada por el propio usuario, y
dentro de unas restricciones existentes, y por root, que es el superusuario y carece de
restricciones.

Tanto el login como la password pueden contener letras como números algunos caracteres
de puntuación, etc., y en ocasiones tienen limitado su tamaño entre un mínimo y un
máximo (normalmente 6 como mínimo y 8 como máximo).

Cada usuario tiene asignado un directorio de trabajo. Varios usuarios pueden tener asignado
el mismo directorio de trabajo, aunque no es lo común.
Así mismo cada usuario tiene asignado un tipo de shell o interprete de comandos. Entre los
tipos de shell más conocidos tenemos ksh, csh, sh, bash, rsh, tcsh, etc.. La diferencia entre
ellas estriba en las utilidades que aportan al usuario, como recuperación de comandos,
variables de entorno, etc.. Si un usuario, en lugar de un interprete de comandos tuviera
asignado un programa, cada vez que accediera al sistema, solo podría ejecutar ese programa
o aplicación, y abandonaría el sistema cada vez que finalizara dicho programa.

Al introducir el login y la password, el sistema verifica que son correctos, anotándolo en un


archivo log. En sistemas de alta seguridad, los accesos incorrectos también pueden ser
almacenados en un archivo y al cabo de varios intentos fallidos, puede bloquearse la cuenta.

Una vez comprobada la validez del acceso, el sistema ejecuta una serie de acciones,
detalladas en el profile general del sistema (/etc/profile por lo general), y que son generales
para todos los usuarios. Entre las acciones principales se pueden destacar:

• Visualización de los archivos de copyright y motd (mensajes que el administrador


ponga para información de los usuarios).
• Establecimiento del TIMEZONE o huso horario.
• Indicación de la existencia de correo.
• Indicación de la hora actual, y de la hora del último acceso.
• Indicación sobre si se ha excedido de un umbral en la ocupación de espacio en
disco.
• Establecimiento de algunas variables de entorno (PATH, LOGNAME, etc.).

Una vez ejecutado el profile general, podrá ejecutarse el profile ( .profile ) particular de
cada usuario, con el cual se completará la definición del entorno del usuario Entre las
acciones que se pueden encontrar en este archivo destacan:

• Establecimiento de las variables de entorno definitivas.


• Establecimiento de aliases, o indicación del archivo que los contiene (.env, .aliases,
etc.).
• Acciones personalizadas del arranque.

Finalmente se ejecutará el programa indicado en el archivo /etc/passwd como shell. Se


finalizará la ejecución de este programa cuando el usuario abandone el sistema, para lo cual
habrá que introducir el comando exit, o pulsar la secuencia Ctrl-D, dependiendo del
sistema.

ACCESOS REMOTOS
Es posible acceder de una máquina a otra siempre y cuando exista un camino físico por el
que hacerlo, un cable directo, una red, etc.

Para que un usuario de un sistema determinado pueda acceder a un sistema remoto será
necesario que tenga una cuenta de usuario en dicho sistema, y que los accesos remotos
estén permitidos.

Cuando se accede a un sistema remoto, los comandos se ejecutarán en la máquina o host


remoto, si bien las entradas y salidas estándar estarán en el sistema local. Se puede decir
que el sistema local se limita a interconectar al usuario con el sistema remoto, de forma
transparente. Esto no es del todo cierto, pues quedan registros de las conexiones
establecidas, etc. en el sistema local.

Para acceder a un sistema habrá que conocer su dirección IP (AAA.BBB.CCC.DDD, donde


cada uno de los 4 valores tomará valores entre 0 y 255) y/o nombre.

Una forma de conocer si un sistema es accesible es mediante el comando ping, mediante el


cual el sistema local envía mensajes al sistema remoto y espera respuesta. Si se recibe
respuesta, no se pierde ningún paquete, es que el sistema está accesible.

ping [DIR-IP]

Para saber si un sistema es accesible por su nombre se puede consultar el archivo /etc/hosts
en el que se identifican los nombres de los sistemas con su dirección IP.

Existen diferentes comandos para acceder a sistemas remotos, entre los que destacan:

• telnet telnet sistema


• rlogin rlogin sistema [ -l usuario ]

Así mismo existen comandos para transferencia de archivos de un sistema a otro sin
necesidad de establecer una sesión directamente en el sistema remoto, entre los que
destacan:

• ftp ftp sistema


• rcp rcp [usuario@]sistema:/directorio/archivo [usuario@]sistema:
/directorio

Se pueden ejecutar comandos en un sistema remoto mediante el comando remsh:

remsh sistema [ -l usuario ] comando

También se puede enviar y recibir correo de usuarios de otros sistemas, para ello, habrá que
indicar el nombre del usuario de destino y el nombre del sistema, con una nomenclatura
como la usada en Internet:
usuario@host

Por motivos de seguridad, cada vez que se intenta acceder a un sistema se pedirá login y
password. Existe la posibilidad de que no se pida, cuando se ejecute rlogin, rcp o remsh, y
consiste en generar un archivo, bajo el directorio de usuario de la máquina remota, llamado
.rhost, en el que se especifica los hosts o sistemas y usuarios que pueden acceder como el
usuario propietario de dicho directorio. Los nombres de sistemas definidos deben coincidir
con los definidos en el archivo /etc/hosts.equiv . Esto es útil sobre todo cuando el nombre
de usuario coincide en los dos sistemas. Si el nombre de usuario fuera diferente, habría que
especificar en el comando de conexión el nombre del usuario del sistema remoto para evitar
la petición de password.

La estructura del archivo .rhost en un sistema remoto es del tipo:

sistema_local_1 login_usuario_local_1 # Comentario_1


sistema_local_2 login_usuario_local_2 # Comentario_2

Se pueden habilitar o inhabilitar usuario y/o sistemas con los signos "+" y "-".

VARIABLES DE ENTORNO

Las variables de entorno, como su nombre indica son variables, pueden ser diferentes para
cada usuario, y permiten personalizar el entorno UNIX a gusto del usuario.

Por lo general, parece que por convenio, en UNIX las variables de entorno se escriben en
mayúsculas (no hay nada que impida que vayan en minúsculas, salvo evitar confusiones
con comandos). Las llamadas a las variables de entorno se realizan anteponiendo el signo
"$" al nombre de la variable ($HOME, $PS1, etc.). Las variables de entorno no pueden
contener el carácter "$" ni espacios, salvo en el valor, siempre y cuando este se presente
entrecomillado.

En UNIX existen unas variables de entorno básicas, que son necesarias para que el usuario
pueda trabajar adecuadamente. Además, tanto el propio usuario como algunos programas
que este ejecute, pueden generar nuevas variables de entorno. Podemos así distinguir entre
variables de entorno generales y variables de entorno particulares.

Las variables de entorno generales difieren poco, en cuanto a nombre se refiere, entre los
distintos sistemas UNIX, y expresan lo mismo en cada sistema.

Las variables de entorno se pueden definir en los archivos de inicialización, al arrancar un


programa, o desde la shell de usuario, y en cualquiera de los casos se definen de la
siguiente forma:
NOMBRE=valor

Y si se desea exportar esta variable, para que sea visible fuera del programa, habrá que
hacer:

export NOMBRE
o
export NOMBRE=valor

Para visualizar el valor de una variable de entorno, basta con teclear:

echo $NOMBRE

Entre las variables generales más habituales encontramos:

• EDITOR : Variable que almacena el editor que usará el usuario por defecto.
• ENV : Variable que almacena el archivo en donde el usuario ha definido sus aliases
y funciones.
• HOME : Variable que almacena el directorio del usuario, desde el que arrancará la
shell cuando entra en el sistema.
• HOSTNAME : Variable que almacena el nombre de la máquina.
• LOGNAME : Variable que almacena el nombre o login del usuario.
• MAIL : Variable que almacena el archivo que contiene el correo de usuario.
• MAILCHECK : Variable que indica cada cuantos segundos debe comprobarse si el
usuario tiene correo.
• PATH : Variable en la que se encuentran almacenados los paths de aquellos
directorios a los que el usuario tiene acceso directo, pudiendo ejecutar comandos o
programas ubicados en ellos sin necesidad de acceder a dicho directorio.
• PS1 : Variable que almacena el prompt que se empleará por defecto en la shell.
• PS2, PS3, etc. : Variable que almacena el prompt que se empleara en la 2ª, 3ª, etc.
Subshells, lo cual se hace invocando a la shell,es decir, ejecutando por ejemplo, ksh.
• PWD : Variable que almacena el directorio actual, puede ser útil para modificar el
prompt (PS1) dinámicamente.
• SHELL : Variable que almacena el interprete de comandos que usa el usuario.
• TERM : Variable que almacena el tipo de terminal desde el que se está trabajando.
• TMOUT : Variable que almacena el tiempo de inactividad que se permite al usuario
antes de que el sistema le cierre la sesión.

COMILLAS Y MAS COMILLAS


Uno de los mayores quebraderos de cabeza de muchos usuarios en UNIX es el tema de las
comillas, que significan y cuando se usan.

Existen los siguientes tipos:

• " : Se emplean para delimitar una cadena de caracteres.


• ' : Son equivalentes a las anteriores.
• ´ : Se emplean para reflejar el resultado de un comando.

Por ejemplo:

A = 'cat prueba'
B = "cat prueba"
C = ´cat prueba´

Al teclear:

echo $A

aparecerá el mensaje:

cat prueba

Lo mismo sucederá al teclear:

echo $B

Pero al teclear:

echo $C

Se mostrará el contenido del archivo prueba, es decir, en la variable C, se ha almacenado el


contenido de dicho archivo como resultado de la ejecución de un comando.

Como ejemplo consideremos el siguiente bucle:

for i in "a b c d e f g"

do

Lo que sea

done

Se realizará para cada elemento indicado en la lista. Si dicha lista es el contenido de un


directorio, sería equivalente a:
for i in ´ls´

do

Lo que sea

done

Este segundo caso presenta la ventaja de ser independiente de los archivos que existan en el
directorio, pues se recogerá cualquier modificación que se dé en dicho directorio, mientras
que en el primer caso, el bucle se ceñirá a los archivos especificados, si no existen dará
error, y si se genera alguno nuevo no se tendrá en cuenta.

SISTEMAS DE ARCHIVOS

UNIX es un sistema operativo, al igual que DOS, en el que la organización de los archivos
es jerárquica, organizada en directorios, presentando una estructura en forma de árbol, en
donde los directorios son ramas y los archivos hojas. El directorio raíz (/) es el directorio
principal, del que cuelgan subdirectorios, de los que a su vez cuelgan otros directorios o
subdirectorios, etc.. En principio se puede suponer que no existe limitación en cuanto a
amplitud como profundidad de la estructura, pero en realidad si existe dicha limitación,
dependiendo esta de la versión, del espacio en disco disponible, etc.

Un sistema de archivos es equivalente a una unidad lógica en MSDOS, pero mientras en


DOS se referencia automáticamente con una unidad (por ejemplo c:), en UNIX es necesario
montarla (hacerla accesible). Montar un sistema de archivos consiste en asignar un
directorio, o punto de montaje, a la unidad lógica. El montaje de un sistema de archivos se
realiza con el comando mount, y el desmontaje con el comando umount. Ambas tareas solo
son realizables, en principio, por root.

mount Dispositivo Directorio Monta el Dispositivo en el directorio especificado.


mount Muestra los dispositivosmontados.
umount Directorio Desmontael Directorio especificado.

Mientras en DOS una unidad lógica no puede extenderse más allá de la unidad física, es
decir, no puede ser mayor que la unidad física, en UNIX si puede extenderse a varias
unidades físicas, si bien esto depende de la versión de UNIX que se tenga cargada.

Entre los sistemas de archivos más comunes tenemos:


• / : Sistema de archivos raíz
• /home : Sistema de archivos para ubicación de los directorios de usuario.
• /tmp : Sistema de archivos para temporales. Puede estar ubicado en memoria RAM
(disco RAM), con lo que el acceso será más rápido.
• /usr : Sistema de archivos para archivos ejecutables, documentación, referencia.
• /var : Sistema de archivos para logs, auxiliares, archivos que crecen.

En UNIX existe una estructura de directorios que difiere poco de un sistema a otro. Entre
los directorios más comunes tenemos:

• / : directorio raíz. De él cuelgan todos los demás directorios.


• /bin : archivos ejecutables, comandos de usuario.
• /cdrom : punto de montaje de CD.
• /dev : archivos de dispositivos (discos, terminales, etc.).
• /etc : archivos de configuración, administración e información del sistema.
• /floppy : punto de montaje de disquetes.
• /home : archivos de usuarios.
• /lib : archivos de bibliotecas de desarrollo y material de apoyo.
• /lost+found : archivos perdidos.
• /mnt : punto de montaje de dispositivos externos.
• /sbin: archivos ejecutables de administración.
• /tmp : Archivos temporales o zona de trabajo de algunos programas UNIX.
• /usr : archivos ejecutables, documentación, referencia.
• /var : archivos log y auxiliares.

En UNIX cualquier dispositivo se trata como un archivo. Un terminal tiene asociado un


archivo, y por tanto si se escribe algo en ese archivo, aparecerá por el terminal. Lo mismo
sucede con las impresoras, módem, etc..

/dev/rmt/0m Primera unidad de cinta.


/dev/floppy Unidad de disquete.
/dev/ttyXX Terminales.

Para acceder a un directorio se puede utilizar el path o camino relativo o absoluto. El path
absoluto se referencia al directorio raíz, por lo que siempre comenzará por el carácter "/"
indicativo del directorio raíz. El path relativo, en cambio, se referencia al directorio en que
se encuentra el usuario en ese momento (comenzará por ".." si se refiere al directorio
superior al actual, o por "." o el nombre de un subdirectorio si se refiere al un subdirectorio
del directorio actual).

cd /usr/bin Path absoluto


cd ../bin Path relativo
En UNIX los archivos tienen permisos para el usuario, para el grupo del usuario y para el
resto de usuarios. Con esto se puede hacer que un archivo sea accesible para un
determinado usuario, o grupo de usuarios, que solo pueda modificarlo un usuario, etc. Los
permisos de un archivo se indican con 10 caracteres se asignan con números:

Al ejecutar el comando "ls -l" nos aparecerá al principio de cada línea una información del
tipo:

-rwxrwxrwx usuario grupo ...

El primer carácter hace referencia al tipo de archivo. El primer grupo rwx hace referencia al
usuario propietario del archivo. El segundo grupo corresponde a los usuarios que
pertenecen al mismo grupo que el propietario. El tercero pertenece al resto de usuarios.
Root tiene acceso ilimitado a todos los archivos, aunque no tengan activado ningún
permiso. Si aparece la letra indica que está permitido ese permiso, y si aparece un guión
indica que está prohibido.

El carácter de tipo de archivo puede ser:

• - : archivo normal.
• b : archivo controlador de dispositivo orientado a bloques.
• c : archivo controlador de dispositivo orientado a caracteres.
• d : directorio.
• l : enlace simbólico

Los caracteres de tipo de permiso son:

• r : acceso a lectura (4).


• w : acceso de escritura (2).
• x : acceso de ejecución (1).
• - : sin permiso (0).

Para cambiar los permisos de un archivo se utiliza el comando chmod (change mode):

chmod 750 archivo o chmod u=rwx g=rx o=-rwx archivo

Dará permiso de lectura, escritura y ejecución para el propietario, de lectura y ejecución


para el grupo de usuarios al que pertenezca el propietario, y ningún permiso para el resto
de usuarios.

Para cambiar el propietario de un archivo se utiliza el comando chown (change owner) y


para cambiar el grupo del usuario chgrp (change group):

chown fulanito[:grupo] hace que fulanito pase a ser el propietario de archivo. Se puede
archivo especificar también el grupo.
hace que el grupo users sea considerado como grupo del
chgrp users archivo
propietario

Existen unos permisos especiales que son:

• s (Bit s): Hace que cualquier usuario que ejecute el programa adquiera la identidad
del propietario durante la ejecución. (4000). También se puede hacer que el usuario
que lo ejecute pase a ser del grupo del propietario durante la ejecución (2000).
• t (Sticky bit): Hace que el programa se lea la primera vez de disco, y quede
residente en memoria, con lo que la próxima vez que se ejecute se cargará más
rápidamente (1000).

En UNIX existe la posibilidad de generar enlaces a archivos o directorios, de forma similar


a lo que sucede en Windows 9X con los accesos directos. Los enlaces no son una copia del
archivo, si no que son referencias a un archivo, pero a la hora de trabajar son equivalentes
al propio archivo, se pueden editar, modificar, etc., y los resultados se actualizan en el
archivo original.

Para enlazar archivos se emplea el comando ln (link):

ln [opciones] archivo directorio_destino

Los enlaces pueden ser físicos (hard) o simbólicos.

• Los enlaces físicos son una copia del archivo, pero cada modificación que se haga
en un archivo se actualizará en el otro, el contenido del archivo no se perderá hasta
que no se borren todos los enlaces. Los enlaces que se generan con el comando ln,
por defecto son físicos.
• Los enlaces simbólicos, en realidad son accesos directos al archivo (denominación
usada en Windows 9X), y si se borra el archivo queda el enlace referido a un
archivo inexistente. Para ello la opción a utilizar con el comando ln es -s.

PROCESOS

Un proceso es un programa en ejecución.

Una de las ventajas de UNIX, como ya se ha indicado, es el multiproceso, lo cual conlleva


la posibilidad de que un usuario pueda estar ejecutando varios procesos simultáneamente
desde un mismo terminal, para ello será necesario lanzar algunos en segundo plano. UNIX
distribuye el tiempo de procesador entre todos los procesos que estén ubicados en la cola de
procesos activos, teniendo en cuenta la prioridad de cada uno de ellos, para ello existe lo
que se llaman rodajas de tiempo, que oscilan de 10 a 100 milisegundos (según la potencia
del equipo), que son ocupadas por los diferentes procesos según una política de asignación.
El multiproceso da origen a las políticas de bloqueo, según las cuales se pueden bloquear
recursos con el fin de evitar problemas. ¿Qué sucede si dos usuarios editan el mismo
archivo? Solo se salvarán los cambios realizados por el usuario que lo salvó en último
lugar. El problema es más crítico en el caso de acceso a bases de datos, escritura en disco,
etc..

En general un proceso consta de varias zonas:

• Código
• Datos
• Pila
• Registro
• Información general

La shell o intérprete de comandos es un programa o proceso que lee los comandos


introducidos por el usuario y genera los procesos hijo necesarios para ejecutar dicho
comando, creándose un árbol de procesos. Cada proceso tiene asociado un número,
denominado pid (identificador de proceso), así como la identidad y grupo del usuario que lo
está ejecutando (uid y gid, respectivamente).

Todo proceso, excepto el proceso raíz (el que tiene pid 0), tiene un proceso padre, que se
puede definir como el proceso desde el cual se lanza el proceso hijo. Cuando finaliza un
proceso padre y los hijos no finalizan adecuadamente, estos quedan activos, pero adoptando
como padre al proceso raíz (el de pid 0). Estos procesos se denominan zombies.

Cada vez que se ejecuta un proceso no se retorna a la shell hasta que este no finalice, salvo
que el proceso se ejecute en segundo plano o background, lo cual se realiza posponiendo el
carácter "&" después de la línea de comando. En caso de ejecutar procesos en background,
es conveniente redirigir las salidas hacia alguna variable de entorno o archivo con el fin de
que la salida del comando no interfiera con las acciones del usuario. El número de
programas que se pueden lanzar en background dependerá de los permisos del usuario, así
como de los parámetros configurados para cada UNIX. Cada vez que se lanza un comando
en background el sistema devuelve un número que indica el pid del proceso.

proceso &

Para matar o finalizar la ejecución de un proceso que se está ejecutando en background


habrá que utilizar el comando kill:

kill [-señal] pid

Donde señal indica el mensaje a enviar al proceso (puede variar entre 1 y 15) y pid es el
identificador del proceso que devolvió el sistema cuando se lanzó el proceso.

Los programas en background finalizan automáticamente cuando el usuario cierra la sesión.


Para evitar esto, se puede forzar a que no finalice anteponiendo "nohup" a la línea de
comando y posponiendo la indicación de background. Por defecto la salida se redirigirá a
un archivo llamado nohup.out.

nohup proceso &

En UNIX existen unos procesos bastante peculiares, cada uno de los cuales se encarga de
una misión y que son los que permiten el perfecto funcionamiento del sistema. Se trata de
los demonios (daemon). Estos procesos a su vez pueden arrancar otros procesos o
demonios con tareas más específicas.

Los demonios son procesos que arrancan cuando se inicializa el sistema y no finalizan
nunca, salvo que se les envíe una señal de finalización, la cual, en circunstancias normales
no se envía más que cuando se va a parar el sistema.

Son procesos, que solo root puede matar o inicializar. Generalmente solo los inicializará
manualmente en caso de que se realice alguna modificación en los archivos de
configuración que lo exija, para que se vuelvan a leer los parámetros de ejecución, o en
caso de algún problema.

Entre los demonios más conocidos podemos encontrar:

• cron : Responsable de las tareas programadas por los usuarios vía crontab.
• getty : Responsable de la gestión de terminales para accesos al sistema, etc.
• inetd : Responsable de los servicios de internet (conexión a otros sistemas).
• init : Responsable de la ejecución de procesos.
• lp : Responsable del manejo de impresoras.
• mail : Responsable de la gestión del correo.
• xntpd : Responsable del intercambio de mensajes con otros sistemas para
sincronización horaria.

Para visualizar los procesos activos en un sistema se puede utilizar el comando ps:

ps [opciones]

Ejemplos:

ps -ef Muestra todos los procesos activos en formato largo.


ps -fu usuario Muestra todos los procesos asociados al usuario especificado

PROGRAMACION DE TAREAS
Los sistemas UNIX están diseñados para estar bastante tiempo activos o en
funcionamiento, a diferencia de los PC que en cuanto se finaliza la jornada se apagan, los
sistemas UNIX siguen en funcionamiento. Esto es debido fundamentalmente a dos factores:

• Tiempo necesario para tirar y levantar el sistema, y las diferentes aplicaciones que
corren en él. No se puede apagar del mismo modo que un PC(los cuales, con el
nacimiento de Windows se van aproximando a los sistemas UNIX).
• Estabilidad del software, mientras que DOS exigía reiniciar el PC con asiduidad,
UNIX podía estar corriendo meses sin reiniciar el sistema. También aquí DOS y
Windows parecen que van mejorando poco a poco.

Si un sistema es estable y se tarda tiempo en pararlo y arrancarlo, ¿Por qué no dejarlo


encendido?. Esta cuestión se convierte más en una afirmación cuando el sistema es usado
por diferentes turnos de personal.

Si el sistema está funcionando cuando el usuario no está delante del sistema. ¿Por qué no
dejar alguna tarea programada, para que cuando llegue al día siguiente tenga menos trabajo
que hacer?. Aquí es donde surge el tema de la programación de tareas.

Un usuario puede dejar programado la generación de informes que consuman un tiempo


apreciable, de modo que no tenga que estar mirando al monitor a la espera de que el sistema
finalice su ejecución. Además de este modo se descarga el sistema, con lo cual las
aplicaciones que se ejecuten irán más rápidas y los demás usuarios se lo agradecerán.

Para programar tareas es conveniente utilizar los periodos de menos carga del sistema,
sobre todo si se trata de tareas que consuman bastantes recursos. Es conveniente
programarlas a las horas en que menos usuarios haya conectados al sistema, con el fin de
que los que estén conectados noten lo menos posible la ejecución de dichas tareas. Para
ello, lo ideal es contactar con el administrador del sistema, quien debe conocer la carga del
sistema en cada momento, y quien puede permitir o denegar la programación de tareas a un
usuario.

Entre las tareas típicas que se ejecutan en modo programado habitualmente, se pueden
destacar:

• Backup incrementales
• Volcado de datos hacia históricos
• Limpieza de archivos
• Ejecución de informes diarios
• Gestión de los accounting (datos sobre cargas del sistema, conexiones de usuarios,
comandos ejecutados, etc.)

Para la programación de tareas existen, fundamentalmente, dos comandos:

crontab crontab archivo


at at hhmm

La diferencia entre ellos estriba en que mientras con el comando at se programa la


ejecución de una tarea para un momento determinado, mediante el cron se pueden
programar por días de la semana, hora, mes, etc..

El cron en realidad es un demonio (programa que esta siempre en ejecución) que lee y
realiza las tareas programadas por los usuarios en un archivo. Cada usuario tendrá su
archivo cron, y existirá una copia del mismo en el directorio /var/spool/cron/crontabs (el
directorio puede variar según el sistema), que es de donde en realidad lo lee el demonio.

Como el usuario que programa las tareas, normalmente no está durante la ejecución de las
mismas, lo normal es que reciba los resultados (si ha salido bien o mal) por un correo. Se
pueden direccionar los resultados a archivos con el fin de analizar la ejecución de las tareas.

En general pueden existir los siguientes archivos, en los que el administrador autoriza o
desautoriza la programación de tareas a los usuarios introduciendo el login en ellos:

• at.deny
• at.allow
• cron.deny
• cron.allow

La estructura de estos archivos es muy sencilla, tan solo hay que incluir el nombre del
usuario en el archivo correspondiente para permitirle o denegarle la posibilidad de
ejecución de tareas programadas.

Un usuario podrá programar tareas si aparece el archivo .allow, si este archivo no existe
podrá programar tareas siempre y cuando no aparezca en el .deny. Si el archivo .deny está
vacio, todos los usuarios pueden ejecutar tareas programadas, y si no existe ninguno,
únicamente root podrá programar tareas. Es decir, el archivo .allow tiene preferencia ante el
.deny.

Para activar y/o desactivar la ejecución de comandos vía cron se utiliza el comando
crontab.

A continuación se muestra un ejemplo de cómo deben ser las líneas incluidas en el archivo
en que se programan las tareas a ejecutar vía cron:

mm hh dd MM ss Comandos

donde:

mm : Minuto dentro de la hora (0-59)


hh : Hora del día (0-23)
dd : Día del mes (1-31)
MM : Mes del año (1-12)
ss : Día de la semana (0-6, Domingo=0)
Comandos : Secuencia de comandos a ejecutar, deben ir separados con ";",
pudiéndose redireccionar tanto la salida estándar como la de errores hacia
algún archivo (2>&1).

Cuando cualquiera de los campos se marca con un "*" se quiere indicar que esa línea se
debe ejecutar para cada valor del campo (cada minuto, cada hora, etc.). En caso de
especificar varios valores dentro de un campo se deben separar con comas ",", y se quieren
especificar rangos, se deben separar con guiones "-".

Las líneas que comienzan por "#" no se ejecutarán, se entenderá que se trata de un
comentario.

Se debe tener cuidado a la hora de programar tareas vía cron con las variables de entorno,
pues cron, por defecto toma unos valores estándar, por lo que cualquier modificación debe
especificarse en la línea de comandos o en un shell script que sea invocado en la línea de
comandos.

En caso de que dos usuarios tengan un cron en el que coincidan, a la misma hora, los
mismos programas, se pueden producir resultados inesperados si se actúa sobre los mismos
archivos.

TUBERIAS Y REDIRECCIONES

En UNIX, al igual que en cualquier sistema operativo, existen 3 dispositivos de entrada


salida que son fundamentales:

• Entrada estándar, tiene el descriptor de archivo 0.


• Salida estándar, tiene el descriptor de archivo 1.
• Error estándar, tiene el descriptor de archivo 2.

Por defecto, la salida estándar y el error estándar están direccionados hacia la pantalla del
terminal, y la entrada estándar corresponde al teclado. Pero en ocasiones puede ser que no
nos interese que la información salga en pantalla, si no que nos interesa filtrarla o
redireccionarla a un archivo para guardar la información o para un tratamiento posterior, o
que la entrada a un programa sea el resultado de la ejecución de otro. Con este fin los
sistemas operativos permiten la utilización de tuberías y redirecciones.

Existen los siguientes tipos de redirecciones:

 Redirección de la salida estándar:


• >: La salida se envía al archivo especificado, borrando el contenido que
hubiera en él (si existiera).
• >>: La salida se añade al contenido del archivo especificado. No se borra el
contenido de dicho archivo, y si no existe se crea.
• |: La salida estándar se emplea como entrada del comando especificado a
continuación. Este se conoce como pipe o tuberías.

Ejemplos:

• ls -l > resultado Almacenará el resultado obtenido con el comando ls -l en


el archivo llamado resultado.
• ls -l | grep prd* Mostrará los archivos que comiencen por prd. Es
equivalente a ls -l prd*.
• ls -l | pg Mostrará página por página el resultado del comando ls -l

 Redirección de la entrada estándar:


• <: Se usa el contenido del archivo especificado a continuación como entrada
estándar del comando especificado delante del símbolo "<".

Ejemplo:

• mail pepe < mensaje Enviará el contenido del archivo mensaje, vía correo
electrónico al usuario pepe.

Las redirecciones más empleadas son las de salida estándar.

La utilización de tuberías puede ahorrar la utilización de archivos intermedios y en


consecuencia disminuir el tiempo de proceso.

La introducción de redirecciones permite mejorar los resultados obtenidos y son básicas a


la hora de realizar shell scripts.

Para fusionar la salida estándar y la salida de errores se puede hacer usando 2>&1.

comando 2>&1 [archivo]

Si nos interesara únicamente redireccionar la salida de errores, habría que utilizar:

comando 2> archivo

EXPRESIONES REGULARES
En algunos comandos como grep, sed, awk se aceptan lo que se conoce como Expresiones
Regulares, que son una forma de describir cadenas de caracteres, y que sirven para buscar o
tratar patrones con caracteres variables (búsquedas y sustituciones complejas).

Existen metacaracteres, que son caracteres que en una expresión regular son interpretados
por su significado especial, y no por los caracteres que normalmente representan. Para
utilizar el carácter que representan habrá que anteponerles el carácter Back Slash (\). Entre
estos caracteres tenemos:

\*?|+^$.()[]{}

Para buscar un rango de caracteres se pueden expresar entre corchetes ([ ]), usando comas
(,), para expresar listas de valores, o guiones (-) ,para expresar rangos de valores, como
separadores. En este caso algunos metacaracteres pierden su valor y pasan a representar el
propio carácter.

El caracter admiración (!) niega el patrón al que precede.

Por ejemplo:

ls -l [A-Z]*
Mostrará todos los archivos (y sus propiedades) cuya
primera letra sea mayúscula.

ls -l [!A-Z]*
Mostrará todos los archivos (y sus propiedades) cuya
primera letra sea no mayúscula.

ls -l [a-z]*
Mostrará todos los archivos (y sus propiedades) cuya
primera letra sea minúscula.
ls -l [a,e,i,o,u]* Mostrará todos los archivos que comiencenpor vocal.
ls -l [!a,e,i,o,u] Mostrará todos los archivos que no comiencenpor vocal.

grep [0-9] archivo


Muestra todas las líneas de archivoque contengan algún
número.
sed `1,$ s/[a-z]/[A-Z]/g`
archivo Cambia todas las minúsculasa mayúsculas de archivo.

ESTAMENTOS
En UNIX existen expresiones o estamentos que se pueden usar en la línea de comandos y
que pueden ejecutar una acción u otra dependiendo de ciertas condiciones, o ejecutar una
tarea un número de veces determinado. Las expresiones más habituales son:

• ASIGNACION: Asigna un valor (numérico o cadena de caracteres) a una variable.

variable = valor

• MANIPULACION DE NUMEROS: Permite realizar las operaciones básicas con


números:

variable = ´expr objeto1 objeto2´

• TEST: Prueba si es cierta una condición, devolviendo TRUE (0) o FALSE (1):

test [condición]

En la condición, para comparar se utilizarán los siguientes operadores:

o = : Para indicar igualdad.


o != : Para indicar desigualdad
o -eq : igualdad.
o -neq : no igual, desigualdad.
o -lt : menor.
o -gt : mayor.
o -le : menor o igual.
o -ge : mayor o igual.

• IF: Si condicional. Si la condición que se prueba es cierta se realiza una acción o


acciones, y si es falsa se realizan otras.
• if [ condición ]
• then
• acción
• else
• otra acción
• fi
• CASE: En caso de que una variable tome un valor hacer una acción, en caso de que
tome otro otra, etc. Equivale a varios if anidados.
• case variable in
• valor_1) acción 1;
• acción 2;;
• valor_2) acción 3;;
• *) acción n;;
• esac
• WHILE: Mientras se cumpla la condición especificada se ejecutarán las acciones
contenidas en el interior del bucle.
• while [ condición ]
• do
• acción
• done

• Until [ condición ]
• do
• acción
• done

Until se puede utilizar como la negación de la condición de while.

• FOR: Para la lista de argumentos dada, ejecutará el contenido del bucle.


• for i in lista
• do
• acción
• done
• FUNCIONES: Se emplean para realizar tareas que tengan cierta entidad por si solas
y que se ejecuten más de una vez. Permiten reutilizar código y ahorrar líneas de
programa, a la vez que reducen el tamaño del programa. Se declaran del siguiente
modo:
• function nombre ()
• {
• acciones;
• }

• nombre ()
• {
• acciones;
• }

Para llamarlas solo habrá que utilizar su nombre seguido de los posibles argumentos
(como si se llamara a un programa más):

Nombre_Funcion argumento1 argumento2

Una función puede llamar a otras funciones o programas, o llamarse a si misma


(recursividad). En el caso de usar funciones que se llamen a si mismas, o funciones
recursivas, hay que tener especial cuidado con las condiciones de salida, con el fin
de no entrar en un bucle infinito.
VARIABLES ESPECIALES

En UNIX existen unas variables especiales que pueden resultar útiles para conocer detalles
sobre programas ejecutados, argumentos, etc.. Estas variables dependen de la shell
utilizada, en el caso de ksh podemos destacar:

• $1 - $9 : Argumentos pasados al programa.


• $0 : Nombre del programa que se está ejecutando.
• $# : Número de argumentos que se han pasado al programa.
• $* : Argumentos pasados al programa.
• $? : Valor devuelto por el último programa que se ejecuto.
• $! : Número de proceso del último proceso que se ejecuto en background.
• $$ : Número de proceso de la shell actual.

SHELL SCRIPTS

Los shell scripts son programas escritos con comandos UNIX y son equivalentes a los batch
de DOS, aunque bastante más potentes, pues admite ejecuciones en segundo plano y tiene
un conjunto de expresiones mucho más amplio.

Para realizar una shell script en condiciones, al igual que para realizar un programa en
cualquier lenguaje de programación, es necesario tener claro lo que se quiere obtener y de
que situación se parte. Es mejor perder un poco de tiempo en realizar un desarrollo mental
del programa que dedicarse a teclear y probar cosas, pues lo más seguro es que no se
consiga el objetivo, y si se consigue la estructura del programa no será la adecuada.

Una de las ventajas que presentan los shell scripts es que pueden ser portadas de una
máquina UNIX a otra sin problemas, sin necesidad de retocar nada, salvo que se utilicen
llamadas a programas muy concretos específicos de una versión de UNIX, mientras que los
programas compilados (desarrollados en C, Pascal, etc.) deben ser recompilados, pues el
código se generará en función del microprocesador de cada máquina. Otra ventaja es la
facilidad de lectura e interpretación.

El principal inconveniente que presentan respecto a los programas compilados es la lentitud


de ejecución. Otro inconveniente es que el código resulta visible a cualquier usuario que lo
pueda ejecutar.
Se deben añadir comentarios con el fin de facilitar la lectura del programa. Los comentarios
se insertan anteponiendo el carácter "#" al comentario, que se extenderá hasta el final de la
línea.

Los scripts suelen encabezarse con comentarios que indican el nombre de archivo y lo que
hace el script. Se colocan comentarios de documentación en diferentes partes del script para
mejorar la comprensión y facilitar el mantenimiento. Un caso especial es el uso de "#" en la
primera línea, seguido del carácter admiración y el path de la subshell, para indicar el
intérprete con que se ejecutará el script:

#!/bin/ksh

Es interesante saber que muchos comandos devuelven un valor después de ejecutarse, y que
este valor indicará si la ejecución ha sido buena o si ha habido algún fallo y que tipo de
fallo se ha producido. Para conocer si un comando devuelve o no un valor y qué es lo que
devuelve en cada caso se deberá consultar la documentación, pero por lo general en caso de
una ejecución correcta devolverán el valor 0, y en caso de fallo otro numero, positivo o
negativo.

Para poder ejecutar un archivo de comandos es necesario que tenga activados, al menos, los
permisos de lectura y ejecución.

A continuación vamos a ver unos ejemplos, comenzando por cosas muy sencillas.

Ejemplo1:

# Programa que cambia de directorio y nos muestra donde estamos en cada


# momento. Cambia directorio en un subshell, no altera ambiente original
#
echo SUBSHELL.
DIRACT=`pwd`
echo Directorio actual $DIRACT
echo Cambiando directorio en el subshell...
cd /etc
echo Ahora en directorio `pwd`
cd
echo Ahora estoy en mi directorio, que es `pwd`
# fin subsh.cmd

El programa mostraría lo siguiente:

SUBSHELL.
Directorio actual /home/jagar
Cambiando directorio en el subshell...
Ahora en directorio /etc
Ahora estoy en mi directorio, que es /home/jagar

Ejemplo 2:

# Programa que muestra la hora del sistema cada segundo durante 1 minuto
Cont=0
while [$Cont -le 60 ]
do
date
Cont=`expr $Cont + 1`
sleep 1
done

Ejemplo 3:

# Programa que nos dice el dia de la semana que fue ayer


HOY=`date +%w` # En la variable HOY almacenamos el numero de dia para
hoy.
AYER=`expr $HOY - 1` # y en ayer, el valor de HOY menos 1

echo "Ayer fue \c"


case $AYER in
-1) echo "Sabado";;
0) echo "Domingo";; # date +%w devuelve el día de la semana
1) echo "Lunes";; # en formato numerico, con valores
2) echo "Martes";; # comprendidos entre 0 (domingo) y 6
3) echo "Miercoles";; # (sabado). En nuestro caso, ayer
tomara
4) echo "Jueves";; # valores entre -1 y 5.
5) echo "Viernes";;
*) echo "un dia raro, pues no existe";;

esac

Ejemplo 4:

#!/bin/ksh
# Programa que pide al usuario que introduzca una cadena de caracteres y
# la muestra, por pantalla del derecho y del revés.
#
echo "Introduce una cadena: \c"
read NOMBRE
LONGITUD=`echo $NOMBRE | wc -c`
while [ $LONGITUD -gt 0 ]
do
NOMBREALREVES="$NOMBREALREVES"`echo $NOMBRE | cut -c$LONGITUD`
LONGITUD=`expr $LONGITUD - 1`
done
echo "\n$NOMBRE\n$NOMBREALREVES"

El programa mostraría en pantalla:

Introduce una cadena: Hola que tal?

Hola que tal?

¿lat euq aloH

Ejemplo 5:

#!/bin/ksh
# Programa que simula una papelera de reciclaje, mediante el cual en
lugar de
# borrar un archivo, lo que hace es guardarlo en un subdirectorio, con el
fin
# de evitar borrados accidentales.
#
if [ $# -gt 0 ]
then
for i in $*
do
echo "Moviendo $i al directorio $HOME/borrados"
if [ `mv $i $HOME/borrados 2> /dev/null` ¡= 0 ]
then
echo "Error, no se puede mover $i"
fi
done
else
echo "Error: hay que especificar argumentos"
echo "$0 archivo1 [archivo2] ..."
return 1
fi
return 0

Ejemplo 6:

# Programa que ejecuta un proceso largo, y mientras tanto va mostrando un


punto en la pantalla, simulando que el proceso va progresando.

function puntos ()
{
if [ $1 ] # Si se ha pasado algun argumento
then
INTERVALO=$1 # Considerar el intervalo como tal
else
INTERVALO=5 # Si no se ha pasado, considerar 5
fi
while true # Ejecutar siempre, sin fin.
do
echo ".\c" # Imprimir un punto si salto de linea
sleep $INTERVALO # Esperar el intervalo especificado
done
}
# Programa principal
# Lo que sea
puntos 2 & # Se llama a la funcion puntos, con intervalos de 2 sg
[ programa que tarda mucho ]
kill -9 $! # Se mata el ultimo proceso lanzado en background
# Lo que sea
# Fin del programa

Ejemplo 7:

# Programa encargado de comprobar la hora de los diferentes sistemas


conectados
# a un sistema determinado
#
# En la variable SISTEMAS_TOT se definen los sistemas de los que se
intentara
# obtener la hora.

SISTEMAS_TOT="maquina1 maquina2 maquina3 maquina4 maquina5 maquina6


maquina7"

#
# La funcion hora se encarga de pedir la hora al sistema especificado,
# filtrarla y mostrarla por pantalla.
#

hora()
{
hora=´telnet $1 daytime 2> /dev/null | grep ":" ´
echo "$hora -----> $1"
}

#
# Comprobar si el sistema esta accesible, y si lo esta, anadirlo a la
variable
# SISTEMAS, que sera la que contiene los sistemas accesibles.
#

for SISTEMA in $SISTEMAS_TOT


do
/usr/sbin/ping $SISTEMA -n 1 | grep " 0% packet loss" >
/dev/null
if [ $? = 0 ]
then
SISTEMAS="$SISTEMAS $SISTEMA"
else
echo "$SISTEMA no esta accesible"
fi
done

#Para los sistemas accesibles comprobar la hora de los mismos en


background
#para minimizar diferencias.

for SISTEMA in $SISTEMAS


do
hora $SISTEMA &
done

#
#Esperar a que finalice la ejecucion de todas las tareas en background.
#

wait

#
#Fin de programa
#

EDITOR VI

El editor vi es el editor por excelencia de UNIX. Es bastante potente y complicado de


manejar a pleno rendimiento, debido a la gran cantidad de opciones que tiene, pero es fácil
dar los primeros pasos e ir avanzando poco a poco. Es difícil de utilizar al principio, pero
puede llegar a convertirse en el más cómodo y rápido.

En UNIX existen otros editores más potentes, con entornos de trabajo más amigables, otros
más sencillos de manejar, pero el único editor que está en todas las versiones y se maneja
igual es el vi.

La sintaxis del comando vi es, al igual que la de cualquier comando UNIX:

vi [opciones] archivo

Entre las opciones más importantes se pueden destacar:

• -r : Recupera la copia del archivo que existe en los directorios temporales. Es útil en
caso de que se haya apagado el terminal sin haber salvado el texto.
• -c : Ejecuta el comando, de vi, que se indica a continuación. Es útil para
posicionarse en algún punto del archivo
En vi existen 3 modos de trabajo:

• Modo comando: cada tecla tiene un significado, y se puede desplazar el cursor,


copiar, pegar, mover, borrar, etc. Hay que tener mucho cuidado, pues un comando
en minúsculas o en mayúsculas tienen efectos muy diferentes.
• Modo texto: se emplea para añadir o modificar el texto del documento.
• Modo ex: inserción de comandos del editor de líneas ex. Se emplea para cambios
masivos en el documento.

En las páginas siguientes se detallan los comandos más importantes de vi clasificados según
el modo en que se ejecutan y las tareas que realizan.

vi es independiente del tipo de terminal, pero la variable de ambiente TERM debe estar
fijada correctamente. Si no se conoce o no existe, en la base de datos de terminales del
sistema, el tipo exacto de terminal con el que se está trabajando, se puede usar el tipo vt100
o el ansi (dan buenos resultados en la mayoría de los terminales).

Para modificar el tipo de terminal se deberá teclear:

TERM=[tipo de terminal];export TERM


o directamente:

export TERM=[tipo de terminal]

Con algunos comandos, especialmente more y a veces vi, el terminal o el emulador que se
está usando pueden no responder bien, que no aparezcan los cambios que se realizan
correctamente en la pantalla. En estos casos, puede usarse Ctrl-l para refrescar la pantalla.

Un usuario puede generar bajo su directorio $HOME un archivo llamado .exrc, en el que
podrá adaptar el entorno del editor vi a su gusto. En este archivo se pueden incluir:

• Opciones set

set [opcion[=valor]]

• Abreviaturas ab

ab [abr] [cadena]

• Macros map.

map [Key|#n] [acción]

donde:

• Key : expresa una letra especial (no utilizada en vi). Por ejemplo v, V, q, K, Ctrl-A,
etc. Las teclas correspondientes a las flechas se pueden definir como macros si es
que no se encuentran definidas por defecto.
• n : expresa un número
• acción : es un comando de vi, teniendo en cuenta que antes de teclear un Escape o
Return, o cualquier carácter de control hay que teclear Ctrl-v.

Tanto las opciones, como las abreviaturas y macros se pueden definir en modo ex para la
edición en curso, pero solo tendrán valor durante la edición actual, no siendo válidas para
las siguientes llamadas al comando vi. Por ello, para que afecte a cualquier llamada del
comando vi, será necesario insertarlas en el archivo .exrc.

MODO TEXTO

Acceso a modo texto


i Insertar antes del cursor.
I Insertar al principio de la línea.
a Añadir después del cursor.
A Añadir al final de la línea.
o Abrir línea debajo de la actual.
O Abrir línea encima de la actual.
R Sobreescribir (cambiar) texto.
r Sobreescribir el carácter sobre el que está el cursor.
c Reemplaza caracteres.
cw Reemplaza palabras.
C o c$ Reemplaza hasta el fin de línea.
c0 Reemplaza desde el comienzo de línea.

Los comandos de reemplazo admiten multiplicadores que consisten en un número


antecediendo al comando. Al dar un comando de reemplazo el editor coloca un símbolo $
en donde termina el pedido de reemplazo. El usuario sobrescribe normalmente hasta donde
necesite, y sale con la tecla ESC. Estos comandos admiten multiplicadores, por ejemplo
3cw abre un área de reemplazo para 3 palabras.

Otros

BS (Back Space) Borrar carácter hacia la izquierda.


ESC Salir de Modo Texto y pasar a modo comando.

MODO COMANDO

Algunos de estos comandos admiten multiplicadores, que consisten en un número


antecediendo al comando.
Movimiento del cursor y Control de pantalla

flechas Mover en distintas direcciones.


h ó BS (Back
Space) Una posición hacia la izquierda.
l ó SP (Espacio) Una posición hacia la derecha.
k ó - Una línea hacia arriba.
j ó + Una línea hacia abajo.
$ Fin de línea.
0 (Cero) Principio de línea.
1G Comienzo del archivo.
G Fin del archivo.
18G Línea número 18.
Ctrl-G Mostrar número de línea actual.
w Comienzo de la palabra siguiente.
e Fin de la palabra siguiente.
E Fin de la palabra siguiente antes de espacio.
b Principio de la palabra anterior.
^ Primera palabra de la línea.
% Hasta el paréntesis que aparea.
H Parte superior de la pantalla.
L Parte inferior de la pantalla.
M Al medio de la pantalla.
23| Cursor a la columna 23.
Ctrl-f Una pantalla adelante.
Ctrl-b Una pantalla atrás.
Ctrl-l Refrescar la pantalla.
Ctrl-d Media pantalla adelante.
Ctrl-u Media pantalla atrás.

Búsqueda

/str Buscar hacia adelante cadena de caracteres 'str'.


?str Buscar hacia atrás cadena de caracteres 'str'.
n Buscar siguiente (si se usó /) o anterior (si se usó ?).
N Buscar anterior (si se usó /) o siguiente (si se usó ?).
fc Buscar el siguiente carácter 'c' en la línea.
Fc Buscar el anterior carácter 'c' en la línea.
tc Ir al carácter anterior al siguiente 'c'.
Tc Ir al carácter posterior al precedente 'c'.
; Repetir el último comando f, F, t, o T.
, último comando f, F, t, o T en sentido inverso.

La cadena a buscar en / o ? puede ser una expresión regular.

La acción de f, F, t y T alcanza sólo a la línea actual; si el carácter buscado no está en esa


línea el cursor no se mueve.

Borrar, Copiar y Pegar

x Borrar carácter bajo el cursor.


dd Borrar línea, queda guardada.
D Borrar desde cursor a fin de línea.
dw Borrar desde cursor a fin de palabra.
d$ Borrar desde cursor a fin de línea.
d0 Borrar desde cursor a principio de línea.
d) Borra hasta el final del párrafo.
Y o yy Copiar línea.
P Pegar antes del cursor.
p Pegar después del cursor.
yw Copiar palabra.
y$ Copiar de cursor a fin de línea.
"ayy o "aY Copiar línea en buffer llamado 'a'.
'a' "ayw Copiar palabra en buffer llamado 'a'.
"ap Pegar desde buffer 'a', a la derecha del cursor.
"aP Pegar desde buffer 'a', a la izquierda del cursor.
"bdd Borrar línea y guardar en buffer 'b'.
"bdw Borrar palabra y guardar en buffer 'b'.
J Unir la línea actual y la siguiente (suprimir el retorno de carro).

Otros

ZZ Grabar cambios si los hubo y salir.


u Deshacer última acción.

U
Deshacer todos los cambios en una línea desde que se posicionó el cursor
en ella.
. Repetir el último comando.

MODO EX O ULTIMA LINEA

Generales

:q Salir si no hubo cambios.


:q! Salir sin guardar cambios.
:w Guardar cambios.
:w arch1 Guardar cambios en archivo arch1.
:wq Guardar cambios y salir.
:r arch2 Insertar un archivo.
:e arch2 Editar un nuevo archivo.
:e! arch2 Idem sin salvar anterior.
:r! comando Insertar salida de comando.
:shell Salir al shell (vuelve con exit).
:.= Muestra el número de línea en que se halla en cursor.

Mover

:1 Mueve a línea 1.
:15 Mueve a línea 15.
:$ Mueve a última línea.

Opciones, abreviaturas y macros

:set Cambio de opciones.


:set nu Mostrar números de línea.
:set nonu No mostrar números de línea .
:set showmode Mostrar modo actual de vi.
:set noshowmode No mostrar modo actual de vi.
:ab [abr] Cada vez que se teclee la cadena abr, ésta se expandirá escribiendo
[cadena] cadena.
:ab Muestra las abreviaturas creadas.
:una [abr] Elimina la abreviatura abr.
:map [c] [accion] Genera la macro c que ejecutará la acción indicada.
:map Muestra las macros definidas.

Otros

Reemplaza todas la primera ocurrencia de la cadena


:[desde],[hasta] s/
[buscar]/[reemplazar]/ [buscar], en cada línea, por la cadena [reemplazar] entre las
líneas [desde] y [hasta] del archivo.
Reemplaza todas las ocurrencias de la cadena [buscar] por
:[desde],[hasta] s/
[buscar]/[reemplazar]/g la cadena [reemplazar] entre las líneas [desde] y [hasta] del
archivo.
:[desde],[hasta] d
Borra las líneas comprendidas entre las líneas [desde] y
[hasta].

Ejemplos:

:1,$s/Martes/martes/g Cambia Martes por martes en todo el archivo.

:.,5s/ayuda/&ndo/g
Cambia ayuda por ayudando desde línea actual
hasta la 5ª línea.

:.,$ d
Elimina todas las líneas desde la línea actual al final
del archivo.

:ab pp Hola Pepe


Cada vez que se teclee "pp " se expandirá en "Hola
Pepe".

SED

Sed es un editor de texto que acepta como entrada un archivo, lo lee y modifica línea a
línea mostrando el resultado en pantalla. Posee muchas características de ed y ex. La
sintaxis general del comando sed es:

sed [-n] [-e'script'] [-f archivo] archivo1 archivo2 ...


donde:

-n : indica que se suprima la salida estándar.


-e : indica que se ejecute el script que viene a continuación. Si no se emplea
la opción -f se puede omitir -e.
-f : indica que los comandos se tomarán de un archivo

Un script consiste en uno o varios comandos del editor (uno por línea) con la siguiente
estructura:

[inicio[,fin]] funcion [argumentos]

donde inicio y fin hacen referencia a las líneas (número de línea) afectadas (o intervalo de
líneas), función hace referencia al comando de editor a aplicar y argumentos hace
referencia a los argumentos necesarios para la ejecución de la función.

Para expresar los comandos en varias líneas, al final de cada línea se debe añadir el carácter
backslash (\) antes de pulsar el Return y aparecerá un prompt con el símbolo mayor que (>).
Ejemplos:

sed '1,$ s/[a-z]/[A-


Cambia todas las minúsculas a mayúsculas de archivo.
Z]/g' archivo
sed '3d' archivo Borra la 3ª línea de archivo.
sed 'a\Linea insertada' Añade una línea con el contenido "Línea insertada" después de cada
archivo línea del archivo.
sed '1,$ s/^[[\[0-9]m//g
\ Elimina todas las secuencias de Escape del tipo Xm y Zm que se
1,$ s/^[[\[0-9]w//g \ suelen usar para letras en negrita, etc. para vt100 y cambia el
1,$ s/^M/^J/g' formato de los saltos de línea, de un archivo almacenando los
archivo > resultados en un archivo nuevo.
archivo.nuevo

Comandos usuales de sed

a\ Añade al final de la línea.


c\ Cambia el contenido del patrón.
d Borra las líneas afectadas.
g realiza sustituciones generales.
i\ Inserta sobre los patrones afectados.
p Imprime las líneas afectadas, incluso con la opción-n.
q Abandona el proceso cuando se alcanza la línea especificada.
r archivo Lee un archivo, añadiendo su contenido a la salida.
w archivo Copia la línea en archivo.
= Imprime el número de línea.
! comando Aplica el comando si la línea no está seleccionada.

AWK
Introducción

El nombre awk proviene de las iniciales de sus desarrolladores : Alfred V. Aho, Brian W.
Kerningan y Peter J. Weinberger, de los Laboratorios Bell de AT&T. Inicialmente se
desarrolló para escribir programas muy cortos, pero las características de este atrajo a los
usuarios de tal modo, que lo impulsó más allá de la idea original de los autores. En 1985
apareció una nueva versión llamada nawk, en la que se implementan características nuevas
como son:

• Funciones de usuario.
• Expresiones regulares dinámicas con sustitución de texto.
• Mayor número de funciones intrínsecas y variables.
• Nuevos operadores y estamentos.
• Entrada de múltiples archivos.
• Acceso a argumentos en la línea de comandos.
• Mejora de los mensajes de error.

awk es un lenguaje de búsqueda y procesamiento de patrones. Esto quiere decir que awk es
capaz de buscar un patrón dentro de un archivo (al igual que grep) y tratarlo según unas
operaciones determinadas. Con awk se pueden desarrollar auténticos programas.

Según esto awk es capaz de procesar un archivo con datos organizados por columnas y
generar nuevas columnas con los valores resultantes de realizar ciertos cálculos u
operaciones.

A diferencia de comandos Unix como grep y sed, que filtran y procesan texto, awk
incorpora su propio lenguaje de programación, siendo capaz de ofrecer operaciones
aritméticas, relaciones lógicas y variables. Se pueden desarrollar programas con awk que
procesen la entrada estándar o un archivo, realizando tareas como tratar archivos de texto
como bases de datos. El lenguaje de programación awk incluye estamentos como for, while
e if-else, así como un conjunto de funciones y variables incorporadas.

Sintaxis

La sintaxis de awk es:

awk [-f archivo_programa] [-Fc] ['programa'] [variable=valor ...] [archivo]

donde:

archivo_programa : especifica el archivo fuente del programa a aplicar a


archivo.
c : especifica el carácter delimitador de campos. Por defecto se considera el
espacio en blanco.
programa : especifica el conjunto de patrones e instrucciones a ejecutar con
archivo. La diferencia con archivo_programa, es que en este caso hay que
especificar los patrones e instrucciones en la línea de comandos. Para evitar
interferencias con la shell deben ir encerradas entre comillas simples (').
variable=valor : se utiliza para establecer los valores que tomarán las
variables que utilice el programa.
archivo : archivo que será procesado por awk. Si se especifica "-" se
interpretará como la entrada estándar.

Campos y Variables

Una línea de entrada se divide en campos separados por espacios, y cada campo se
denomina como $1, $2, etc. $0 indica la línea entera. Estas variables se pueden manipular
(sumar, cambiar, etc.) como cualquier otra varible, por ejemplo:
awk '{ $1 = $2 + $3; print $0 }' archivo

Sumará los campos 2 y 3 en el campo 1, e imprimirá el nuevo registro (la línea completa).

Se pueden referir a los campos con expresiones numéricas como $i, $(n+1), $(NF*3/NR),
etc. Si la expresión resultante no es un entera, se truncará la parte decimal. El tratamiento
de un campo como texto o numérico dependerá del contexto, awk resuelve las posibles
ambigüedades tratando los campos como texto (por ejemplo cuando se compara un texto
con un número), por ejemplo:

x=10 Asigna a x el valor numérico 10


x="Hola" Asigna a x la cadena Hola
Asigna a x el valor 4, como si se hubiera escrito x=2+2, debido a que el
x="2"+"2"
contexto demanda un valor numérico.

En los programas de awk no es necesario declarar las variables (indicar el tipo de variable
de que se trata), se realizará automáticamente en función del contexto. Por defecto se
inicializan a la cadena nula o valor numérico 0, por lo que no es necesario inicializarlas.

Existen unas variables predefinidas, que pueden ser utilizadas dentro del programa:

• FS : Separador del campo de entrada. Se puede especificar con la opción -Fc en la


línea de comandos
• RS : Separador de registro de entrada
• OFS : Separador del campo de salida.
• ORS : Separador de registro de salida
• NF : Número de campos en el registro actual
• NR : Número de registros procesados hasta el momento. Al final del programa se
podrá conocer el número e registros tratados.
• RSTART : Posición de la cadena en la que se verifica el patrón utilizado,
comenzando desde 1. Es equivalente al valor retornado por la función match.
• RLENGTH : Longitud de la cadena en la que se verifica el patrón utilizado.
• SUBSEP : Separador de cadenas en arrays multidimensionales. El valor por defecto
es " 34".

Los valores de las variables relativas a separadores se pueden modificar en cualquier


momento, asignándole el valor de cualquier carácter. Por defecto, los separadores de
campos son espacios, y los de registros el carácter nueva línea.

Formato de los estamentos

La estructura general de los estamentos o conjuntos patrón-acción es:

Patrón { acción }

Interpretación:
• Para cada línea que verifique lo especificado en el patrón, se ejecutará la acción
indicada.
• La acción siempre va encerrada entre llaves.
• Se pueden especificar varias acciones, separándolas por ";" o por el carácter nueva
línea.

Si no se especifica la acción, se mostrarán por pantalla aquellas líneas que contengan el


patrón. La acción está formada por estamentos (if, for, print, sprintf, next), los cuales deben
finalizar en ";", Nueva Línea o llaves. Dentro de las acciones se pueden realizar
operaciones matemáticas, de concatenación, etc. Las variables utilizadas pueden ser
escalares, campos o tablas, y son inicializadas a la cadena nula.

Los patrones deben ir rodeados por caracteres "/", y puede contener dos patrones separados
por una coma, en cuyo caso la acción se realizará para aquellas líneas comprendidas entre
la primera aparición del primer patrón y la siguiente aparición del segundo patrón. Si se
utiliza el símbolo "~", indicará que el patrón de la derecha está contenido en el campo de la
izquierda, y si se utiliza "!~", indicará que no está contenido.

Existen dos etiquetas opcionales, con un significado especial, que hacen que un programa
awk tenga una estructura como la siguiente:

BEGIN { acción }
Patrón { acción }
END { acción }

La acción indicada en la etiqueta BEGIN se ejecutará antes de leer cualquier entrada,


mientras que la acción asociada a la etiqueta END se ejecutará una vez tratadas todas las
entradas. La etiqueta END se puede utilizar para imprimir resultados totales, o cálculos
realizados con todos los registros leídos.

Cuando el conjunto patrón-acción se introduce desde la línea de comandos, se recomienda


que vaya encerrado entre comillas simples, para protegerlo de la shell. Por ejemplo:

Desde un archivo Desde la shell de Unix


length > 60 awk 'length > 60'

A continuación se muestran los diferentes tipos de acciones y estamentos.

if (expresión) estamento [else estamento]


while (expresión) estamento
for (inicialización ; final ; incremento)
estamento
for (var in array) estamento
do estamento while (expresión)
break
continue
[ [estamento] }
expresión por ejemplo una asignacion var=valor
print [lista de expresiones] [ > expresión]
printf formato[, lista de expresiones] [ >
expresión]
return [expresión]
salta los elementos restantes de la línea de
next
entrada
delete array [expresión] Borra un elemento array
Finaliza la ejecución del programa,
exit [expresión]
devolviendo el valor indicado en expresión.

Operaciones

Un programa awk puede hacer operaciones en coma flotante, utilizando los siguientes
operadores:

+, -, *, / Adición, sustración, multiplicación y división


% Operador módulo o resto.
++, -- Operador de incremente y decremento
+=, -=, *=, /=, %= Asinación al estilo C (x += 1 equivale a x = x + 1)

Funciones Incorporadas

Las siguientes funciones se pueden utilizar para la realización de operaciones aritméticas y


con cadenas de caracteres.

Función Descripción
length(x) Devuelve la longitud del argumento
sqrt(x) Devuelve la raíz cuadrada del argumento
log(x) Devuelve el logaritmo en neperiano del argumento (en base e)
exp(x) Devuelve el valor de e elevado al argumento
int(x) Devuelve la parte entera del argumento
cos(x) Devuelve el coseno del argumento
sin(x) Devuelve el seno del argumento
atan(x) Devuelve el arcotangente del argumento
rand() Devuelve un número aleatorio comprendido entre 0 y 1
Devuelve la posición de s en donde ocurre r, comenzando desde 1. Si no
match(s,r)
existe devuelve 0.
substr(s,m,n) Devuelve la subcadena de s que comienza en la posición m y finaliza en
la n.
Sustituye la primera ocurrencia de t por r en la cadena s. Si no se
sub(r,t,s)
especifica s se tomará todo el registro ($0).
gsub(r,t,s) Igual que sub, pero sustituyendo todas las ocurrencias.
Divide la cadena s en array[1],...,array[n]. Se devuelve el número de
split(s,array,sep) elementos. Si no se especifica el separador en sep se utilizará el valor de
FS. s puede ser una variable.
Devuelve la posición de la cadena s1 en donde se encuentra la cadena s2.
index(s1,s2)
En caso de no encontrarse se devuelve 0.
Devuelve la cadena resultante de imprimir los valores e1, e2, ... con el
sprintf(f,e1,e2,...)
formato especificado en f.
toupper(s) Devuelve la cadena s convertida a mayúsculas.
tolower(s) Devuelve la cadena s convertida a minúsculas.
Ejecuta el comando UNIX cmd especificado y retorna el estado de salida
system(cmd)
de este.
print e1, e2, ... Presenta en la salida los valores e1, e2, ...
Presenta en la salida los valores e1, e2, ... con el formato especificado
printf f, e1, e2, ...
por f (al estilo C: %s, %d, etc.).
close(f) Cierra el archivo o pipe abierto con print, printf o getline.
Lee el siguiente registro de la entrada y se lo asigna a X, si no se
getline X
especifica X se asignará a $0.

Funciones

Las funciones se pueden definir (en la posición de un estamentopatrón-acción) del siguiente


modo:

function Nombre_Función(p1, p2, p3) { ..., return x }

Los parámetros se pasan por valor si son escalares y por referencia si se pasa el nombre del
array. Los parámetros son locales, mientras que el resto de las variables son globales. Las
funciones pueden llamarse de forma recursiva.

Ejemplos

Ejemplos de patrones

/prueba/ Todas las líneas que contengan la cadena "prueba".


$2 ~ /prueba/ Todas las líneas cuyo segundo campo contenga la cadena "prueba".
$1 !~ /prueba/ Todas las líneas cuyo primer campo no contenga la cadena "prueba".
/start/ , /stop/ Imprime todas las líneas existentes entre los patrones start y stop.
Ejemplos de acciones

{ print $5 } Imprime el campo 5.


{ print $1 $3 } Imprime los campos 1 y 3 consecutivamente.
{ s=$2+$3 ; print s } Suma los campos 2 y 3 e imprime el resultado.
Suma de los campos 2 y 3, e imprime la línea original y
{tot=$2+$3; print $0, tot}
la suma.
Toma como separador de entrada la coma y/o los
BEGIN {FS = ",[ \t]*|[ \t]+" }
blancos y tabulaciones.
{ s += $1; print $2, $1 }
Suma el primer campo de todos los registros e imprime
END { print "La suma es ", s ,
los campos 2 y 1 (en ese orden).
"La media es ", s/NR
Al final imprime el total y la media.

Ejemplos

Imprime los archivos que contengan como propietario, nombre,


ls -l | awk '\txt\ { print
grupo, etc. la cadena txt. El símbolo "-" indica que el archivo es
&8 }' -
la entrada estándar.
Busca cadena en archivo y en una variable llamada cont
awk '\cadena\
(contador) va sumando los valores del campo 2 e imprimiendo
{ cont=cont+$2 ; print
dicho campo, un tabulador y el valor del contador. Al final de la
$2 "\t" cont }' cont=0
salida tendremos la suma total de los valores que ha tenido
archivo
cadena en el campo 2.
awk '$2>0 { print $1," ", Para cada línea de archivo, si el 2º campo es positivo, imprime
$2 }' archivo los dos primeros campos.
awk '$2>0 { printf "%s Idem que el caso anterior, suponiendo que el primer campo es
%d\n", $1, $2 }' archivo una cadena de caracteres.
awk '{gsub(" ","",$0); Elimina todos los espacios en blanco del archivo especificadoy
print $0;}' archivo lo muestra en pantalla.

CGI's

El nombre CGI proviene del inglés Common Gateway Interface, y vienen a ser programas
escritos en cualquier lenguaje que añaden una mayor funcionalidad a las paginas Web. Son
programas que se ejecutan en el servidor, no en la máquina cliente como sucede con los
javascript.

Antes de continuar debo decir que para entender lo que voy a comentar es necesario tener
algunas nociones, aunque sean mínimas de lenguaje HTML.
Un cgi permite construir por ejemplo una página web dinámicamente, tratar los datos de un
formulario, o realizar determinadas tareas en la máquina servidor.

El motivo de hablar aquí de cgi's es debido a la posibilidad de construirlos en shell script.


Hay lenguajes más potentes y flexibles como perl, python, C, VisualBasic, Java, etc. (que
se salen del ámbito de este curso), pero el caso que nos incumbe es que se pueden construir
en shell script. Tampoco voy a dar una clase magistral sobre el tema, pues no soy ni mucho
menos un experto, pero si puedo dar unas pequeñas ideas a aquellos a los que les ha
resultado útil el curso. Si tienes instalado Linux (no sé si trae servidor web con la
instalación) y quieres montar un servidor web, puedes descargarte el Apache desde
http://www.apache.org (venias con la intención de aprender un poco de UNIX y al final
acabas montando un servidor web. Ya es un aliciente). Si tienes Windows, puedes
encontrar también allí una versión especifica para Windows, pero evidentemente los cgi
que vamos a desarrollar aquí no te funcionaran, pero tendrás un servidor web bajo
Windows. No es complicado configurar el Apache para las tareas básicas, pero hay que
leerse las instrucciones que por desgracia vienen en inglés.

Al construir un cgi con comandos UNIX tenemos toda la flexibilidad que dicho sistema
operativo nos proporciona. Además podemos utilizar programas realizados en otros
lenguajes dentro del propio shell script o cgi.

Lo mejor para entender un cgi creo que es mostrar un ejemplo como el siguiente, en el que
construiremos una pagina web titulada prueba en la que aparezca un mensaje.

#!/usr/bin/sh
echo "Content-type: text/html"
echo ""
echo "<html><head><title>P&aacute;gina Web
para probar el primer CGI</title></head>"
echo "<body bgcolor=yellow>"
echo "<H2>PRUEBA CGI</H2>"
echo "<font face=\'Arial, Helvetica\' size=2>"
echo "<p align=\'center\'>Esta p&aacute;gina
se ha creado con mi primer CGI</p>"
echo "</font></body>"
echo "</html>"

Este ejemplo, salvo errores en las comillas deberia funcionar. Este mismo cgi en C seria:

#include <stdio.h>
main()
{
printf("Content-type: text/html\n");
printf("\n");

printf("<html><head><title>P&aacute;gina Web
para probar el primer CGI</title></head>");
printf"<body bgcolor=yellow>");
printf("<H2>PRUEBA CGI</H2>");
printf("<font face=\'Arial,
Helvetica\' size=2>");
printf("<p align=\'center\'>Esta
p&aacute;gina se ha creado con mi primer
CGI</p>");
printf("</font></body>");
printf("</html>");
}

Como se puede ver un cgi se puede escribir en cualquier lenguaje. Antes de seguir adelante,
he de avisar de que para que funciones el CGI debe tener permisos de ejecución, por lo que
habrá que hacer un chmod:

chmod 755 <archivo>.cgi

Es conveniente ponerle la extensión cgi a los archivos de dicho tipo, para evitar por un lado
confusiones a la hora de manipularlos y por otro para evitar errores de funcionamiento.
Podemos observar que en todo cgi las dos primeras líneas de la página que se genere deben
ser:

echo "Content-type: text/html"


echo ""

en donde la primera línea especifica el tipo de contenido de la página. Existen diferentes


tipos, los cuales no vamos a comentar.

Un ejemplo tipico de CGI es un contador de visitas de una pagina web. Aqui vamos a usar
el mismo ejemplo de antes, y mostrar el valor del contador, que se supone que guardaremos
en un archivo llamado contador.txt (el nuevo código insertado va en cursiva), le
incrementamos el valor en 1 (la visita que acabamos de realizar al visualizar la página) y
guardamos el nuevo valor en el mismo archivo, sobreescribiendolo. Ojo, hay que crear el
archivo contador.txt con un valor determinado. Si tras dos pruebas no se incrementa el
contador, dale permiso de escritura al archivo (suele ser algo que se olvida fácilmente):

#!/usr/bin/sh
echo "Content-type: text/html"
echo ""
echo "<html><head><title>P&aacute;gina Web
para probar el primer CGI</title></head>"
echo "<body bgcolor=yellow>"
echo "<H2>PRUEBA CGI</H2>"
echo "<font face=\'Arial, Helvetica\' size=2>"
echo "<p align=\'center\'>Esta p&aacute;gina
se ha creado con mi primer CGI</p>"
echo "<p>Eres el visitante n&uacute;mero: "
CONTADOR=`cat contador.txt`
CONTADOR=`expr $CONTADOR + 1`
echo $CONTADOR > contador.txt
echo "$CONTADOR</p>"
echo "</font></body>"
echo " </html>"
Con lo visto hasta aquí podemos decir que un cgi es un shell script en el que la salida por
pantalla se presenta en formato HTML. Las operaciones que se realizan dentro del cgi son
idénticas a las realizadas con un shell script normal, pudiendo hacer llamadas a programas
desarrollados en otros lenguajes, utilizando herramientas como awk, sed, etc. A modo de
ejemplo, implementaremos el caso anterior con awk.

#!/usr/bin/sh
echo "Content-type: text/html"
echo ""
echo "<html><head><title>Pagina Web para
probar el primer CGI</title></head>"
echo "<body bgcolor=yellow>"
echo "<H2>PRUEBA CGI</H2>"
echo "<font face=\'Arial, Helvetica\' size=2>"
echo "<p align=\'center\'>Esta p&aacute;gina
se ha creado con mi primer CGI</p>"
echo "<p>Eres el visitante n&uacute;mero: "
CONTADOR=`cat contador.txt`
awk '{ contador+=1;}
END { printf "%.5d", contador}'
contador=$CONTADOR
echo $CONTADOR > contador.txt
echo "$CONTADOR</p>"
echo "</font></body>"
echo "</html>"

Si no hay errores con las comillas debería funcionar.

Si la página fuera estática,como sucede en la realidad, habría que llamar al cgi desde la
propia pagina:

....
</p>Eres el visitante N&uacute;mero: <IMG SRC=\"archivo.cgi?
parametro1=valor1&parametro2=valor2&...\" alt=\'Contador\'></p>
.....

Y el cgi realizaria las operaciones antes vistas del contador.

Hasta el momento hemos visto cgi's a los que se llamaría sin pasarle parámetros. Pero
normal es que cuando llamemos a un cgi sea para mostrar una página o realizar una tarea en
función de unos datos suministrados a través de un formulario por ejemplo. Sin quererlo
acabamos de ver como se realiza una llamada al cgi pasándole parámetros. Los parametros
se pasan en una cadena, que habrá que tratar para separar los diferentes parámetros que le
lleguen, lo cual podremos hacer con programas construidos especificamente para ello (en C
por ejemplo) o utilizando algo que hemos aprendido en este curso, el editor sed. Los
parametros dentro del cgi estarán dentro de unas variables de entorno, llamadas
QUERY_STRING y CONTENT_LENGTH. El uso de QUERY_STRING o
CONTENT_LENGTH dependerá del modo en que se envía la información. Existen dos
formas de enviar la información: GET y POST. Si se utiliza el método GET habrá que
emplear QUERY_STRING, y si se emplea el método POST habrá que emplear
CONTENT_LENGTH. Si se emplea el método GET la información no puede superar un
cierto tamaño (1 kb), mientras que si se emplea el método POST no existe dicha limitación,
pues se toma la información de la entrada estándar (stdin). El usar uno u otro método se
especificará a la hora de definir la acción a ejecutar con la información del formulario.

<FORM ACTION="direccion_cgi" METHOD="metodo"


NAME="nombre">
....
</FORM>

Para más información sobre el tema, es conveniente consultar cualquier manual o tutorial
sobre HTML.

En el siguiente ejemplo, vemos como se pueden obtener los parametros que se pasan al cgi,
para poder trabajar con ellos.

#!/usr/bin/sh

if [ $1 ]
then
cadena=$1
else
cadena=`head -c -n$CONTENT_LENGTH`
fi
variable1=`echo $cadena | awk -F "&" '{ print $1 }' | awk
-F "=" '{ print $2 }'`
variable2=`echo $cadena | awk -F "&" '{ print $2 }' | awk
-F "=" '{ print $2 }'`
variable3=`echo $cadena | awk -F "&" '{ print $3 }' | awk
-F "=" '{ print $2 }'`

echo Content-type: text/html


echo ""
echo "<html><head>"
...

Otro ejemplo:

#!/usr/bin/sh

if [ $1 ]
then
cadena=$1
else
cadena=`head -c -n$CONTENT_LENGTH | sed 's/
%2B/+/g
s/%2F/\//g
s/%3A/:/g'`
fi
# Tratamiento de los argumentos
recibidos para utilizarlos en el cgi
Variable1=`echo $cadena | awk '{
if (index($0,cadena1) > 0)
print valor1}'`
Variable2=`echo $cadena | awk '{
if (index($0,cadena2) > 0)
print valor2}'`
Variable3=`echo $cadena | awk '{
if (index($0,cadena3) > 0)
print valor3}'`
...

Otro ejemplo en el que se formatea QUERY_STRING para posterior utilización:

#!/usr/bin/sh
cadena=`echo $QUERY_STRING | cut -c7-200 | sed '1,$ s/
+/|/g'`
echo Content-type: text/html
echo ""
...

Una vez que hemos recibido los parámetros necesarios, tan solo hay que procesarlos, y en
función de los mismos construir la página adecuada.

Creo que con lo visto hasta aquí nos podemos hacer una idea de como construir un cgi, para
profundizar más es conveniente acudir a documentación de lenguaje HTML y cgi´s. Una
dirección que puede resultar útil es http://www.w3.org/. El lenguaje a emplear dependerá
por un lado de los lenguajes que soporte el servidor, de la facilidad para implementar lo que
deseamos construir, y como no, de nuestras preferencias.

VERSIONES DE UNIX
A continucación muestro una tabla, remitida por Luis Reyes, en la que se muestran algunas
versiones existentes de UNIX, así como algunas características y su dirección de Internet.

Fabricante /
Producto Descripción Web
Creador
LINUX Linus Torvalds Es un clon de Unix, http://www.Linux.org
que tomando como
base el Minix,
escribio desde cero
Linus Torvalds,
estudiante de la
Universidad de
Helsinki
(Finlandia), con
asistencia de otros
muchos hackers en
la red que soporta
el software de libre
distribución de
GNU. Tiene todas
las características
que se encuentran
en sus parientes
comerciales y otras
muchas, incluyendo
soporte para
ejecución nativa de
binarios Java. La
versión 0.02 data de
1991, la 1.00 de
1994 y la 2.4 de
2001.
FreeBSD Universidad FreeBSD (versión http://www.FreeBSD.org
Berkeley 2.0) es un sistema
operativo de tipo
Unix basado en la
versión 4.2BSD-
Lite de UCB para
plataforma i386.
También se
encuentra basado
aunque
indirectamente en
el sistema 386BSD
de William Jolitz.
Dada su similitud
con NetBSD
aplazaremos la
discusión de sus
características hasta
el próximo
apartado. No
obstante diremos
que es un sistema
extensivamente
utilizado tanto en
empresas como en
entornos
domésticos. Su
software de red es
excelente como
revela el hecho que
empresas dedicadas
a comunicaciones
entre ordenadores
lo utilicen como
plataforma básica.
NetBSD Universidad El proyecto http://www.NetBSD.org
Berkeley NetBSD ha surgido
como resultado del
esfuerzo de un gran
número de personas
que tienen como
meta producir un
sistema operativo
tipo Unix accesible
y libremente
distribuible.
NetBSD está
basado en una gran
variedad de
software de libre
distribución que
incluye entre otros,
a 4.4BSD Lite de la
Universidad de
California-
Berkeley, a Net/2
(Berkeley
Networking
Release 2) el
sistema de ventanas
X del MIT y
software de GNU.
AIX IBM Basado en el http://www.ibm.com/servers/aix/
sistema operativo
Unix System V.
Basado en SVR2
HP-UX HP Basado en el http://unix.hp.com/operating/index.html
sistema operativo
Unix System V
OpenBSD www.OpenBSD.org Sistema operativo http://www.OpenBSD.org
libre tipo Unix,
multiplataforma,
basado en 4.4BSD.
SPARC- Tatung Basado en el http://www.tsti.com/
OS sistema operativo
UNIX BSD
SunOS SUN Basado en el http://www.sun.com/SunOS/ ?
sistema operativo
UNIX BSD.A
partir de la versión
2 pasa a
denominarse
Solaris
Solaris SUN Basado en el http://www.sun.com/solaris/
sistema operativo
UNIX BSD
XENIX Microsoft Basado en el http://www.microsoft.com/
sistema operativo
Unix System V
IDRIX Basado en el
sistema operativo
Unix System V
System V AT&T System V es la http://www.att.com/
versión más
ampliamente usada
de UNIX. Es el
descendiente
directo del UNIX
desarrollado por
AT&T en 1969.
Está actualmente en
la revisión 4.1 y a
menudo es
referenciado como
SVR4, o System V
Release 4.
ULTRIX DEC ahora Basado en el http://www.compaq.com/
COMPAQ sistema operativo
Unix System V
SolOS Solobourne Basado en el http://www.sun.com
Computers sistema operativo
UNIX BSD
Solinux SUN Basado en el http://www.sun.com/
sistema operativo
Unix System V
UnixWare Novell http://www.novell.com/
OSF/1 DEC, HP, IBM
Minix Andrew S. Para PC y VAX. Se
Tanenbaum distribuye con los
fuentes.Compatible
con la versión 7

Algo de Unix
En esta sección voy añadiendo cosas que me van pareciendo interesantes, a nivel general,
basándome en las actividades habituales. Tened en cuenta que las escribo casí de memoria,
por lo que no sería extraño que hubiera algún error. En tal caso me gustaría que me lo
comentarais para subsanarlo. Si conoceis alguna utilidad y quereis exponerla decídmelo.

¿Como emular el DOSKEY en UNIX (Esc-K)?

En el archivo $HOME/.profile deberá exitir, si no existe habrá que añadir en un punto por
el que siempre se pase -generalmente el principio- lo siguiente:

HISTFILE=$HOME/.history
HISTSIZE=64
EDITOR=/usr/bin/vi # el PATH correcto donde se encuentre ubicado el
comando vi
export HISTFILE HISTSIZE EDITOR

Antes de usar $HOME, por supuesto que debe estar definido. El tamaño 64 es
recomendado, puedes poner el que quieras. El nombre del archivo en principio puede ser
cualquiera, pero eligelo con lógica.

Si trabajas bajo una plataforma con entorno gráficos, es posible que no fucione, para ello
deberás localizar el .profile equivalente, o habilitar algún parámetro definido en dicho
profile, que permita correr el .profile. Bajo la plataforma HP-UX, en el archivo .dtprofile,
bajo tu directorio, hay que activar el parámetro DTSOURCEPROFILE=TRUE (quitale el
comentario (#)). Por supuesto debes reiniciar la sesión en cualquiera de los casos.

Una Papelera de Reciclaje. No borres tus archivos de forma definitiva.


Recuperalos!!!

( ¡ No es aplicable a root por motivos de seguridad en sistemas multiusuario ! )

Crea un directorio (en tu directorio de usuario) con un nombre cualquiera, pero


significativo (p.e. trash). En tu $HOME o en el directorio en que tengas tus ejecutables,
create un archivo llamado rm, e inserta en él:

/bin/mv $* $HOME/trash # /bin se debe sustituir por la ubicación real de


mv
Deberá tener permiso, al menos, de ejecución y lectura para el propietario:

chmod 700 rm

En tu archivo .profile deberás cambiar PATH=..., de modo que aparezca antes el directorio
que contiene el nuevo rm que el directorio que contiene el rm real (/bin o /usr/bin, depende
del sistema), con el fin de que sea localizado antes el nuevo rm que el original.
Con esto lo que se consigue es mover los archivos que se quieren borrar a un subdirectorio,
por si interesara recuperarlos. Deberás limpiar este directorio de forma periódica, para lo
cual te puedes generar un archivo en el mismo directorio que el anterior que contenga una
instrucción como:

/bin/rm $HOME/trash/*

o en el .profile:

find $HOME/trash -atime [DIAS] -exec /bin/rm {} \;

Backgrounds activos

Si ejecutas un shell script que tarda algún tiempo, lo suficiente como para mosquear al
usuario, y quieres que el usuario se crea que todo va bien, prueba a incluir lo siguiente en tu
shell script (puedes cambiar el punto que se imprime por cualquier carácter o símbolo, pero
cuidado con las secuencias de escape):

function puntos ()
{
if [ $1 ]
then
tiempo = $1 # Lo que le indiques
else
tiempo = 5 # 5 segundos por defecto
fi
while true
do
echo ".\c"
sleep $tiempo
done
}

Programa principal:

puntos 1 & # Cada segundo imprimirá un punto


PROGRAMA # programa a ejecutar
kill -9 $! # Finaliza el último programa lanzado en background
presenta los resultados como quieras
if [ -f $out ] # Si se generó el archivo de salida. Prueba a insertar
otras funciones
then
echo "Los resultados estan en $SALIDA"
else
echo "Algo ha fallado"
fi

¿Aliases o Funciones?

Habitualmente los aliases se guardan en un archivo cuyo nombre suele ser .aliases, o .env,
se puede comprobar visualizando la variable de entorno $ENV. En otras ocasiones puede
estar almacenado en el propio .profile. Los aliases vienen a tener la siguiente estructura:

alias ll="ls -l" o alias ll=´ls -l´


alias fcore="find / -name core -print -exec rm{} \;"

pero podemos comprobar que no admiten variables como argumentos. Para solucionar esta
carencia lo que podemos usar son funciones, teniendo en cuenta que $1, $2, etc. Son los
argumentos que se pasan a la función. Evidentemente, al tratarse de funciones, las podemos
construir tan complejas como deseemos, pudiendo llegar a ser auténticos programas.
Como ejemplo veamos la siguiente función que busca una cadena de caracteres en todos los
archivos que cuelgan de un subdirectorio determinado, y en los subdirectorios que a su vez
cuelgan de él, es decir, en el árbol descendente del subdirectorio que elijamos.

function Ffind ()
{
if [ $2 ] # Se comprueba si existe 1 o 2 argumentos
then
DIR_INICIAL=$1
CADENA=$2
else
if [ $1 ]
DIR_INICIAL=.
CADENA=$1
else
echo "Sintaxix: Ffind <directorio>
<cadena>"
return 0
fi
fi
# Ahora obtenemos el árbol de directorios sobre el que hay que
buscar
DIRECTORIOS=´find $DIR_INICIAL -depth -type d -print´
for i in $DIRECTORIOS
do
echo "Buscando $CADENA en $i"
grep $CADENA $i/* # Puedes usar las opciones
que quieras del comando grep
done
}
Esta función estaría en el archivo de aliases y sería de uso exclusivo del propietario,
invisible a los demás.
La puedes mejorar con más opciones, emplear recursividad, etc., el caso es que debe ser útil
y lo más rápida posible, para lo cual debe consumir el mínimo de recursos. La sintaxis que
se emplearía, en el caso expuesto, sería:

Ffind <directorio> <cadena>

Un ejemplo de alias dinámico, que cambie el directorio de acceso en función del año en que
nos encontremos puede ser del tipo:

alias cdano="ANO=`date +%Y` ; cd /home/user/$ANO

El resto es cuestión de imaginación.

Borrar archivos que contienen metacaracteres en su nombre.

En ocasiones se generan archivos, por error o no, que continen caracteres extraños o
metacaracteres como ?, *,^C ,^H, etc. y que no pueden ser borrados habitualmente con el
comando rm. Para eliminar estos archivos se puede emplear el siguiente método:

1. Listar el directorio en el que se encuentre con el comando ls -li, con el fin de anotar
el i-nodo que le corresponde.

ls -li [directorio]

2. Buscar en ese directorio el archivo con el número de i-nodo que le corresponde y


borrarlo:

find [directorio] -inum [i-nodo] -ok -exec rm {} \;

La opción -ok se incluye para que pida confirmación.

Ejecución de comandos en otra máquina sin tener que acceder


explícitamente.

Para ello puedes realizar un rsh (remote shell, no restricted shell) o remsh indicando el
nombre de la máquina, pero si generas un archivo con el nombre de la máquina en tu
directorio de ejecutables, y lo linkas al rsh o remsh podras realizar la misma operación
tecleando simplemente el nombre de la máquina y el comando a ejecutar. Esto viene
documentado, solo tienes que hacer un man rsh (o remsh, dependiendo del UNIX que
tengas cargado) y leer por el medio.

Por supuesto debes tener tener cuenta en dicha máquina y el acceso habilitado mediante el
archivo .rhosts bajo tu directorio.

Archivo creado el 10-Mayo-1999. Ultima actualización 27-Noviembre-2004


Si encuentras algún error, tienes alguna sugerencia o comentario enviame un e-
mail jagar1@teleline.es

You might also like