Sei sulla pagina 1di 46

CONTENIDO

l Introducción
l DOS vs UNIX
l Estructura de los comandos
l Lista de comandos
l Acceso al sistema
l Accesos remotos
l Variables de entorno
l Comillas y mas comillas
l Sistemas de archivos
l Procesos
l Programación de tareas
l Tuberías y redirecciones
l Expresiones Regulares
l Estamentos
l Variables especiales
l Shell scripts
l Editor vi
l Sed
l Awk
l CGI’s
l Versiones de UNIX

Curso UNIX Por José Antonio García http://go.to/jagar Página 1 de 46


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:

l Gestión de la memoria
l Control de las operaciones de Entrada y Salida
l Tratamiento de Interrupciones
l Control del Sistema
l 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:

l Microordenadores: ordenadores personales, PC, etc.


l Miniordenadores: Ordenadores multiusuario, VAX, 3B2, etc.
l Mainframes: Ordenadores con mayor potencia de procesamiento, IBM 370, etc.
l 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 2 de 46


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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 3 de 46


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.

Ejemplo:

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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 4 de 46


LISTA DE COMANDOS

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 dos 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.
finger Devuelve datos sobre la actividad de los usuarios conectados a un 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 5 de 46


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.
nice Permite reducir la prioridad de un proceso. Solo root puede incrementarla.
nohup Realiza tareas en background y envía los resultados al archivo 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.
talk Establece una conexión con otro usuario para mantener una 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.
time Muestra en pantalla el tiempo que ha sido necesario para ejecutar un comando.
touch Modifica la fecha y hora de un archivo. Si no existe lo crea con tamaño 0.

Curso UNIX Por José Antonio García http://go.to/jagar Página 6 de 46


tr Filtro que sirve para intercambiar un carácter por otro.
umask Visualiza y establece permisos para los archivos y directorios que se generen.
umount Desmonta un sistema de archivos.
uname Devuelve información sobre el nombre de la máquina, versión S.O., etc.
uncompress, unpack Descomprime un archivo comprimido.
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.
whence Busca un archivo dentro de los directorios definidos en la variable PATH.
which Localiza un archivo dentro de los directorios incluidos en $PATH y aliases.
who Muestra los usuarios que están conectados al sistema.
write Envía un mensaje a la pantalla del usuario especificado.

Curso UNIX Por José Antonio García http://go.to/jagar Página 7 de 46


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:

l Visualización de los archivos de copyright y motd (mensajes que el administrador ponga para
información de los usuarios).
l Establecimiento del TIMEZONE o huso horario.
l Indicación de la existencia de correo.
l Indicación de la hora actual, y de la hora del último acceso.
l Indicación sobre si se ha excedido de un umbral en la ocupación de espacio en disco.
l 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:

l Establecimiento de las variables de entorno definitivas.


l Establecimiento de aliases, o indicación del archivo que los contiene (.env, .aliases, etc.).
l 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 8 de 46


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:

l telnet telnet sistema


l 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:

l ftp ftp sistema


l 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 “-“.

Curso UNIX Por José Antonio García http://go.to/jagar Página 9 de 46


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:

l EDITOR : Variable que almacena el editor que usará el usuario por defecto.
l ENV : Variable que almacena el archivo en donde el usuario ha definido sus aliases y funciones.
l HOME : Variable que almacena el directorio del usuario, desde el que arrancará la shell cuando
entra en el sistema.
l HOSTNAME : Variable que almacena el nombre de la máquina.
l LOGNAME : Variable que almacena el nombre o login del usuario.
l MAIL : Variable que almacena el archivo que contiene el correo de usuario.
l MAILCHECK : Variable que indica cada cuantos segundos debe comprobarse si el usuario tiene
correo.
l 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.
l PS1 : Variable que almacena el prompt que se empleará por defecto en la shell.
l 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.
l PWD : Variable que almacena el directorio actual, puede ser útil para modificar el prompt (PS1)
dinámicamente.
l SHELL : Variable que almacena el interprete de comandos que usa el usuario.
l TERM : Variable que almacena el tipo de terminal desde el que se está trabajando.
l TMOUT : Variable que almacena el tiempo de inactividad que se permite al usuario antes de que
el sistema le cierre la sesión.

Curso UNIX Por José Antonio García http://go.to/jagar Página 10 de 46


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:

l “ : Se emplean para delimitar una cadena de caracteres.


l ‘ : Son equivalentes a las anteriores.
l ´ : 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 11 de 46


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 dispositivos montados.
umount Directorio Desmonta el 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:

l / : Sistema de archivos raíz


l /home: Sistema de archivos para ubicación de los directorios de usuario.
l /tmp : Sistema de archivos para temporales. Puede estar ubicado en memoria RAM (disco
RAM), con lo que el acceso será más rápido.
l /usr : Sistema de archivos para archivos ejecutables, documentación, referencia.
l /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:

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


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

Curso UNIX Por José Antonio García http://go.to/jagar Página 12 de 46


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:

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

Los caracteres de tipo de permiso son:

l r : acceso a lectura (4).


l w : acceso de escritura (2).
l x : acceso de ejecución (1).
l - : 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] archivo hace que fulanito pase a ser el propietario de archivo. También se
puede modificar el grupo al que pertenecerá el programa.
chgrp users archivo hace que el grupo users sea considerado como grupo del
propietario

Existen unos permisos especiales que son:

l 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).
l 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).

Curso UNIX Por José Antonio García http://go.to/jagar Página 13 de 46


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:

ln [opciones] archivo directorio_destino

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

l 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.

l 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 14 de 46


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:

l Código
l Datos
l Pila
l Registro
l 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 &

Curso UNIX Por José Antonio García http://go.to/jagar Página 15 de 46


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:

l cron : Responsable de las tareas programadas por los usuarios vía crontab.
l getty : Responsable de la gestión de terminales para accesos al sistema, etc.
l inetd : Responsable de los servicios de internet (conexión a otros sistemas).
l init : Responsable de la ejecución de procesos.
l lp : Responsable del manejo de impresoras.
l mail : Responsable de la gestión del correo.
l 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]

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


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

Curso UNIX Por José Antonio García http://go.to/jagar Página 16 de 46


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:

l 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).
l 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:

l Backup incrementales
l Volcado de datos hacia históricos
l Limpieza de archivos
l Ejecución de informes diarios
l 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:

l crontab crontab archivo


l 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 17 de 46


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:

l at.deny
l at.allow
l cron.deny
l 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 si 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 18 de 46


TUBERIAS Y REDIRECCIONES
En UNIX, al igual que en cualquier sistema operativo, existen 3 dispositivos de entrada salida
que son fundamentales:

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


l Salida estándar, tiene el descriptor de archivo 1.
l 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:

q Redirección de la salida estándar:

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

Ejemplos:

l ls –l > resultado Almacenará el resultado obtenido con el comando ls –l en el archivo


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

q Redirección de la entrada estándar:

l <: 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

Curso UNIX Por José Antonio García http://go.to/jagar Página 19 de 46


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.

La 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 comiencen por vocal.
ls –l [!a,e,i,o,u] Mostrará todos los archivos que no comiencen por vocal.
grep [0-9] archivo Muestra todas las líneas de archivo que contengan algún
número.
sed ‘1,$ s/[a-z]/[A-Z]/g’ archivo Cambia todas las minúsculas a mayúsculas de archivo.

Curso UNIX Por José Antonio García http://go.to/jagar Página 20 de 46


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:

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

variable = valor

l MANIPULACION DE NUMEROS: Permite realizar las operaciones básicas con números:

variable = ´expr objeto1 objeto2´

l 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:

§ = : Para indicar igualdad.


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

l 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

l 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

l 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

Curso UNIX Por José Antonio García http://go.to/jagar Página 21 de 46


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

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

for i in lista
do
acción
done

l 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:

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


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

Curso UNIX Por José Antonio García http://go.to/jagar Página 22 de 46


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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 23 de 46


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

Curso UNIX Por José Antonio García http://go.to/jagar Página 24 de 46


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

Curso UNIX Por José Antonio García http://go.to/jagar Página 25 de 46


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

Curso UNIX Por José Antonio García http://go.to/jagar Página 26 de 46


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
#

Curso UNIX Por José Antonio García http://go.to/jagar Página 27 de 46


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:


l -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.
l -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:


l 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.
l Modo texto: se emplea para añadir o modificar el texto del documento.
l Modo ex: inserción de comandos del editor de líneas ex. Se emplea para cambios masivos en el
documento.

Transiciones entre los diferentes Modos

Esc :
Modo Modo Modo
Texto Comando ex
<Comando> Una vez
ejecutado el
comando

Curso UNIX Por José Antonio García http://go.to/jagar Página 28 de 46


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:

l Opciones set
set [opcion[=valor]]
l Abreviaturas ab
ab [abr] [cadena]
l Macros map.
map [Key|#n] [acción]
donde:
l 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.
l n : expresa un número
l 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 29 de 46


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: 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 30 de 46


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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 31 de 46


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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 32 de 46


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] [cadena] Cada vez que se teclee la cadena abr, ésta se expandirá escribiendo 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
:[desde],[hasta] s/[buscar]/[reemplazar]/ Reemplaza todas la primera ocurrencia de la
cadena [buscar], en cada línea, por la
cadena [reemplazar] entre las líneas [desde]
y [hasta] del archivo.

:[desde],[hasta] s/[buscar]/[reemplazar]/g Reemplaza todas las ocurrencias de la


cadena [buscar] por 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].

Curso UNIX Por José Antonio García http://go.to/jagar Página 33 de 46


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".

Curso UNIX Por José Antonio García http://go.to/jagar Página 34 de 46


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-Z]/g’ archivo Cambia todas las minúsculas a mayúsculas de archivo.

sed ‘3d’ archivo Borra la 3ª línea de archivo.

sed ‘a\Linea insertada’ archivo Añade una línea con el contenido “Línea insertada”
después de cada línea del archivo.

sed ‘1,$ s/^[[\[0-9]m//g \ Elimina todas las secuencias de Escape del tipo Xm y Zm
que se suelen usar para letras en negrita, etc. para
1,$ s/^[[\[0-9]w//g \ terminales vt100 y cambia el formato de los saltos de
línea, de un archivo almacenando los resultados en un
1,$ s/^M/^J/g’ archivo > 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 35 de 46


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:
l archivo_programa : especifica el archivo fuente del programa a aplicar a archivo.
l c : especifica el carácter delimitador de campos. Por defecto se considera el espacio en blanco.
l 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 (‘).
l variable=valor : se utiliza para establecer los valores que tomarán las variables que utilice el
programa.
l 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).

Curso UNIX Por José Antonio García http://go.to/jagar Página 36 de 46


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
x="2"+"2" Asigna a x el valor 4, como si se hubiera escrito x=2+2, debido a que el 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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 37 de 46


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]
Next salta los elementos restantes de la línea de entrada
delete array [expresión] Borra un elemento array
exit [expresión] Finaliza la ejecución del programa, 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)

Curso UNIX Por José Antonio García http://go.to/jagar Página 38 de 46


Funciones Incorporadas
Las siguientes funciones se pueden utilizar para la realización de operaciones aritméticas y con
cadenas de caracteres.

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

match(s,r) Devuelve la posición de s en donde ocurre r, comenzando desde 1. Si no existe


devuelve 0.
substr(s,m,n) Devuelve la subcadena de s que comienza en la posición m y finaliza en la n.

sub(r,t,s) Sustituye t por la primera ocurrencia de r en la cadena s. Si no se especifica s se


tomará todo el registro ($0).
g(sub(r,t,s) Igual que sub, pero sustituyendo todas las ocurrencias.

split(s,array,sep) Divide la cadena s en array[1],...,array[n]. Se devuelve el número de elementos. Si


no se especifica el separador en sep se utilizará el valor de FS. s puede ser una
variable.
index(s1,s2) Devuelve la posición de la cadena s1 en donde se encuentra la cadena s2. En caso
de no encontrarse se devuelve 0.
sprintf(f,e1,e2,...) Devuelve la cadena resultante de imprimir los valores e1, e2, ... con el formato
especificado en f.
toupper(s) Devuelve la cadena s convertida a mayúsculas.

tolower(s) Devuelve la cadena s convertida a minúsculas.

system(cmd) Ejecuta el comando UNIX cmd especificado y retorna el estado de salida de este.

print e1, e2, ... Presenta en la salida los valores e1, e2, ...

printf f, e1, e2, ... Presenta en la salida los valores e1, e2, ... con el formato especificado por f.

close(f) Cierra el archivo o pipe abierto con print, printf o getline.

getline X Lee el siguiente registro de la entrada y se lo asigna a X, si no se especifica X se


asignará a $0.

Curso UNIX Por José Antonio García http://go.to/jagar Página 39 de 46


Funciones
Las funciones se pueden definir (en la posición de un estamento patró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.
{tot=$2+$3; print $0,tot} Suma de los campos 2 y 3, e imprime la línea original y la
suma.
BEGIN {FS = ",[ \t]*|[ \t]+"} Toma como separador de entrada la coma y/o los blancos y
{ s += $1; print $2, $1 } tabulaciones.

END { print "La suma es ", s, Suma el primer campo de todos los registros e imprime los
"La media es ", s/NR campos 2 y 1 (en ese orden).
Al final imprime el total y la media.

Ejemplos
ls –l | awk ‘\txt\ { print &8 }’ - Imprime los archivos que contengan como propietario,
nombre, grupo, etc. la cadena txt. El símbolo “-“ indica
que el archivo es la entrada estándar.
awk ‘\cadena\ { cont=cont+$2 ; print $2 Busca cadena en archivo y en una variable llamada
“\t” cont }’ cont=0 archivo cont (contador) va sumando los valores del campo 2 e
imprimiendo dicho campo, un tabulador y el valor del
contador. Al final de la salida tendremos la suma total
de los valores que ha tenido cadena en el campo 2.
Awk ‘$2>0 { print $1,” “, $2 }’ archivo Para cada línea de archivo, si el 2º campo es positivo,
imprime los dos primeros campos.
Awk ‘$2>0 { printf “%s %d\n”,$1,$2 }’ Idem que el caso anterior, suponiendo que el primer
archivo campo es una cadena de caracteres.

Curso UNIX Por José Antonio García http://go.to/jagar Página 40 de 46


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>”);
printf(“<title>P&aacute;gina para probar el primer
CGI</title></head>");
printf"<body bgcolor=yellow>");
printf("<H2>PRUEBA CGI</H2>");
printf("<font face=\'Arial, Helvetica\' size=2>");

Curso UNIX Por José Antonio García http://go.to/jagar Página 41 de 46


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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 42 de 46


#!/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></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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 43 de 46


#!/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.

Curso UNIX Por José Antonio García http://go.to/jagar Página 44 de 46


VERSIONES DE UNIX
A continuació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 Es un clon de Unix escrito desde cero por Linus
Torvalds, con asistencia de otros muchos hackers
en la red que soporta el software de libre
Linus
distribución de GNU. Tiene todas las http://www.Linux.org
Torvalds
características que se encuentran en sus
parientes comerciales y otras muchas, incluyendo
soporte para ejecución nativa de binarios Java.
FreeBSD (versión 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
Universidad
FreeBSD características hasta el próximo apartado. No http://www.FreeBSD.org
Berkeley
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.
El proyecto 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.
Universidad NetBSD está basado en una gran variedad de
NetBSD http://www.NetBSD.org
Berkeley 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.
Basado en el sistema operativo Unix System V.
AIX IBM http://www.ibm.com/servers/aix/
Basado en SVR2
http://unix.hp.com/operating/inde
HP-UX HP Basado en el sistema operativo Unix System V
x.html
SPARC-OS Tatung Basado en el sistema operativo UNIX BSD http://www.tsti.com/
Basado en el sistema operativo UNIX BSD.A partir
SunOS SUN http://www.sun.com/SunOS/ ?
de la versión 2 pasa a denominarse Solaris
Solaris SUN Basado en el sistema operativo UNIX BSD http://www.sun.com/solaris/
XENIX Microsoft Basado en el sistema operativo Unix System V http://www.microsoft.com/
IDRIX Basado en el sistema operativo Unix System V
System V es la versión más ampliamente usada
de UNIX. Es el descendiente directo del UNIX
System V AT&T desarrollado por AT&T en 1969. Está actualmente http://www.att.com/
en la revisión 4.1 y a menudo es referenciado
como SVR4, o System V Release 4.
DEC ahora
ULTRIX Basado en el sistema operativo Unix System V http://www.compaq.com/
COMPAQ
Solobourne
SolOS Basado en el sistema operativo UNIX BSD http://www.sun.com
Computers
Solinux SUN Basado en el sistema operativo Unix System V http://www.sun.com/

Curso UNIX Por José Antonio García http://go.to/jagar Página 45 de 46


UnixWare Novell http://www.novell.com/
DEC, HP,
OSF/1
IBM
Andrew S. Para PC y VAX. Se distribuye con los fuentes.
Minix
Tanenbaum Compatible con la versión 7.

Curso UNIX Por José Antonio García http://go.to/jagar Página 46 de 46

Potrebbero piacerti anche