Unix

Comandos. Sincronización de procesos (pipes y fifos). Fork. Join. AWK. Procesos. Shell. Variables. Puertos. Impresión LPT (Line Print Terminal)

  • Enviado por: El remitente no desea revelar su nombre
  • Idioma: castellano
  • País: España España
  • 55 páginas

publicidad
publicidad

UNIX

cat - Nos permite ver el contenido de un archivo.

ls -li - Nos lista los archivos del directorio actual.

* ls /* ->

* pwd -> Nos dice en que directorio nos encontramos.

* history -> Todo lo que hemos tecleado desde el principio de la sesion.

* finger -> Nos dice quien esta conectado.

Ejemplo:

Login Name TTY Idle When Where

root Responsable del sistema p2 trueno.fi.upm.es

* chfn -> Nos permite cambiar el nombre < name > del finger.

* w -> Nos dice quien esta conectado y que esta haciendo.

Ejemplo:

User tty login@ idle JCPU PCPU what

* more -> Nos permite ver el contenido de un archivo.

* cd -> Permite cambiar de directorio.

* cd .. -> Sube al directorio anterior.

* man -> Manual de ayuda. Su formato es man < comando >.

* rm -> Borra archivos.

* mail -> Para entrar en el correo electronico.

k0123@asterix.fi.upm.es

* telnet -> Para conectarnos con otra máquina.

* connect -> Para conectarnos con otra máquina.

* ftp -> Para poder conectarnos con otra máquina y poder traer ficheros.

Subordenes:

* help

* open -> abre la sesion de ftp

* close -> cierra la sesion de ftp

* bye -> Nos devuelve al prompt del UNIX < $ >

* bin -> Activa el modo binario

* ascii -> Activa el modo ascii

* hash -> Para ver graficamente como va el proceso de

download

* get -> get < filename > Se trae un archivo concreto

* mget -> mget * Se trae todos los archivos

* put -> Lo contrario de get.

* abort -> Anula último comando si no ha terminado de

ejecutarse

* ! -> Solo ordenes del DOS. Ej: !a: !dir c:\juegos

* lcd a: -> Y me puedo traer las "cosas" al diskete a:

* mkdir -> Crea un directorio.

* rmdir -> Borra un directorio.

* logout -> Para cerrar la cuenta y salir.

* exit -> Para cerrar la cuenta y salir.

* mv -> Para renombrar un archivo.

* grep -i -> Busca en un archivo ignorando mayúscula y minúsculas (-i) la

cadena que queramos.


* prog -> prog < lo que sea > para buscar en archie.

* passwd -> Para cambiar el password.

* ps u -> Nos da todos tus procesos abiertos.

* ps u a -> Todos los procesos de todos los usuarios.

PID -> Identificador de proceso

* fg -> Para continuar con un proceso parado con Ctrl-Z

* kermit -> ? ó Help

* kill -> Mata procesos. kill -9 -1 mata todos los procesos y te hecha

a la calle.

Kill -9 <PID> ó número de proceso, mata ese proceso

concretamente.

* chmod ->

* /usr/X11R5/bin/xarchie -> Para poder ejecutar xarchie

* cd /usr/bin/X11/xrn & -> Para poder usar las news

* uuencode < filename > -> De Bin a Ascii

* uudecode < filename > -> De Ascii a Bin

* compress -> Comprime

* uncompress -> Descomprime


Instrucciones para iniciar una sesión UNIX en el AULA-D

RESET

pctcp

win

Telnet> open auladð%

Login: f931069

Password: ********

Para pasar ficheros de MSDOS a UNIX usaremos WFtp en el Administrador de programas de Windows.

Procederemos:

New

Hostname → aulad

User name → f931069

Password → ********

Intro

Para enviar mails:

931092 → Mariano

931040 → Carlos


UNIX

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

- S.O básico (sistema de archivo, directorios, archivos, dispositivos, utilidades)

- Manual

- Editores de texto (ed -líneas-, vi -bloques-)

- Sistema de programación (cc, ld, ar, make)

- Gestor de red (uucp, tcp/ip)

INDICE

1 Sistema de archivo

Dispositivo

- orientados a carácter (tty's)

- orientados a bloque

Archivos ordinarios (de usuario)

- sistema de protección

rwx-rwx-rwx

usuario grupo otros

Archivos directorio

Fifos y Pipes (sincronización de procesos)

Conceptos básicos

- inodo (lista de inodos)

- utilidades

- usuario → gestión de archivos

- mail

- impresión

2 Procesos

Estado (ps)

Prioridad o planificación (nice)

Ejecución

- fork( ) → secundaria

- exec → solapada

3 Programación shell (8 puntos)

Descripción de un lenguaje

- E/S

- estructuras de control

- subprogramas

- estructuras de datos → arrays

AWK (subconjunto del lenguaje C)

4 Administración del sistema (sysadmsh)


CARACTERISTICAS DEL SISTEMA OPERATIVO UNIX

Es un sistema operativo multiusuario y multitarea.

1. Multiusuario

Requisitos de conexión:

1. Tarjeta de red

- Configuración hardware

dirección de memoria de E/S

IRQ (interrupciones HW)

2. Cableados

- Ethernet fino

- Ethernet grueso

- Par trenzado

3. Conectores

- T-BNC

- RJ-45

HARDWARE:

- tarjeta

- conectores

- cables

- concentradores

SOFTWARE:

- protocolo

- TCP/IP

DOS/WINDOWS

Utilidades

-ftp (envío y recepción de archivos entre sistemas)

- telnet (sesión)

Programa ejemplo:

saludo.c

#include <stdio.h>

main( )

{

printf("Hola mundo \n");

}

dir → c:/fuentes


Sesión UNIX

$ls

saludo.c

$make saludo.c cc saludo.c -o saludo

saludo

$saludo

Hola mundo

1. Conectividad en red

2. Software: protocolo TCP/IP

3. Utilidades de conexión (ftp, telnet)

Terminales virtuales: puede haber hasta 12 usuarios en un sólo terminal, conmutando con ALT+tecla de función.

Ordenes de gestión de archivo (copia, borrado, enlace,...): cp, rm, ln, ls, cd, mkdir, rmdir, cat, more, find.

2. Multitarea

Tarea en memoria:

S.PILA.KERNEL

S.PILA

S.DATOS

S.CODIGO

Una tarea es un programa cargado en memoria al que se le asignan segmentos informativos para su contenido:

- segmento de pila

- segmento de datos

- segmento de código

- segmento de pila KERNEL (gestor de tareas del sistema operativo)

Las tareas tienen una identificación (PID y PPID) de tipo entero de 0 a 216. Establece un árbol de dependencias de proceso.

PID: nº que identifica al proceso.

PPID: nº que identifica al proceso padre.

Este esquema establece un árbol de dependenciasnuméricas.

Se determina un proceso inicial, PID0, nombre INIT. El proceso INIT se encarga de la inicialización y el arranque.

Getty verifica los protocolos de comunicación con los terminales.


Esquema:

login envía un proceso de conexión por cada terminal, que verifica la conexión de un teórico usuario al sistema.

Después de la conexión tenemos como último proceso un intérprete de órdenes (shell, equivalente al COMMAND.COM de MS-DOS), que será el padre de todos los procesos que se generen en un terminal.

El concepto de multitarea establece una serie de rangos. Hablamos así de procesos padres, hijos y huérfanos. Se establece la relación tarea-familia.

Proceso huérfano: finaliza el proceso antes que el hijo. En este caso se le asigna como padre shell.

La identificación numérica de todos los procesos permite el envío de señales ($kill -9 432).

Se permite la ejecución interactiva o diferida de procesos:

$ordenð% → modo interactivo

$orden& ð% → modo diferido

El modo diferido presenta el PID (entre corchetes) del proceso que se ejecuta. Se le asigna tiempo de CPU en función de los requisitos. Se ejecuta en segundo plano (background).

La existencia de estos dos modos de ejecución de procesos nos conduce a:

Planificación (batch, crontab, at, notmp)

Podemos planificar temporalmente la ejecución de nuestras tareas.

EJ: ejecutar un programa todos los días a la misma hora, manteniendo la ejecución aunque finalicemos la sesión UNIX.

Esta planificación permite definir contextos de prioridad (nice, sleep, wait) que permiten sincronizar y planificar los procesos.

La versión 4 incorpora la planificación en tiempo real.

3 Sistema de seguridad

Se encarga de gestionar la entrada de usuarios al sistema.

a) Existen 2 archivos ASCII con este fin:

/etc/passwd

/etc/group

Estos ficheros contienen los usuarios que el administrador de sistemas ha dado de alta.


passwd /etc/passwd

id_usuario : clave : nº usuario : nº grupo : comentarios : dir : shell

ð ð ð ð ð ð ð

LOGIN (14 caract) PASSWORD ID NUMERICA GRUPO PERTE. COM.ADM.SISTEMA $HOME INTERPRETE

group /etc/group

nombre_grupo : clave : id_grupo : usuarios

ð ð ð ð

ID ALFANUMERICA OPCIONAL ID NUMERICA LOGIN DE TODOS

LOS USUARIOS

PERTE. AL GRUPO

b) Concepto de usuario efectivo en la aplicación

Tenemos como usuarios muchos programas, que modifican el sistema. Cada programa sólo puede ser usado por el usuario que lo posee. Para ello, el usuario, al ejecutar un programa se convertirá en ese momento en el administrador del sistema, por lo que podrá variar lo que quiera y alterar la instalación.

c) Concepto de grupo efectivo en la ejecución

Cualquier archivo creado pertenecerá a un usuario y a un grupo.

ARCHIVO → UID → GID

Esto se graba en un inodo, generándose una estructura de permisos de lectura, escritura y ejecución.

Variables del sistema → umask 666

usuario rwx

Archivo => inodo grupo rwx

otros rwx

d) Integridad del sistema

Está a cargo de órdenes, se identifica como fsck (equivalecte a CHKDSK). Verifica la consistencia de la estructura del superbloque con la lista de inodos.

La integridad del sistema desaparece si apagamos de golpe el ordenador, por lo que se ejecuta fsck al volver a encender.

fsck → /tmp

/lost+found

Se almacenan las inconsistencias del sistema.

Virus en UNIX:

En MS-DOS se permite la existencia de primitivas que mantengan un párrafo de código en memoria, por ejemplo KEEP.

Un vector de interrupción que se habilita 18 veces por segundo. Se varía cambiándolo por el código del virus. Se produce pseudomultiprogramación.

En UNIX es más fácil localizar los programas en ejecución, por lo que se dificulta la entrada de virus.

Una posibilidad en UNIX es el denominado 'Caballo de Troya' o 'Troyano'


--- su ---

stty -echo

echo "Password: \c"

read x

echo " "

stty echo

echo $1 $2 > temp $ $

sleep 1

echo Clave errónea

rm su

Programa su: Switch User

Sirve para cambiar de usuario. Nosotros simulamos el programa su para encontrar el password del administrador.

Con un parámetro para el login creamos un fichero temporal tempxxx, donde xxx es el PID del proceso echo.

Hacemos creer al administrador que se ha equivocado al introducir el password y después borramos el su. El administrador ejecuta esta vez el su verdadero sin haberse percatado de lo ocurrido.

4 Sistema jerárquico de archivo

A veces, dependiendo del nivel en que nos movamos, podemos ver el sistema de archivo como una secuencia de bloques lógicos, cada uno de los cuales tiene un tamaño fijo (múltiple de 512 bytes).

Estructura lógica Estructura física

%

%/usr [boot][superbloque][ ][ ][ ... ][ ][ ][ ][ ][ ... ][ ][ ]

%/bin \ LISTA DE INODOS /\ BLOQUES DATOS /

%/etc

%/tmp

%/spool

Esta secuencia de bloques nodo se apoya en una estructura fundamental: el inodo.

inodo

[dispositivo ] dispositivo donde se alberga el inodo

[nº inodo ] nº de inodo que hace (índice dentro de la lista de inodos)

[modo ] información sobre el tipo de archivo y accesibilidad

[nº enlaces ] nº de enlaces simbólicos que comparte el archivo

[UID ] id del usuario propietario del archivo

[GID ] id del grupo propietario del archivo

[dispositivo ] campo especial para dispositivos

[tamaño ] tamaño en octetos

[fecha último acceso ] lectura

[fecha última notificación ] escritura

[fecha cambio administrativo] estadística

El inodo identifica un archivo.


CAMPO INODO

%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%

TIPO ARCHIVO ð ð ð USUARIO GRUPO OTROS (ACCESIBILIDAD AL ARCHIVO) 100 r - lectura, 010 w - escritura, 001 x - ejecución

% % %% BIT DE PERMANENCIA: MANTIENE EL ARCHIVO EN MEMORIA

% %%% GRUPO EFECTIVO EN EJECUCION

%%%% USUARIO EFECTIVO EN EJECUCION

TIPO DE ARCHIVO

1000 ORDINARIO

0100 DIRECTORIO

0010 DISPOSITIVO ORIENTADO A CARACTER (TERMINAL)

1100 DISPOSITIVO ORIENTADO A BLOQUE (DISCO DURO)

0001 FIFO (SINCRONIZACION)

1010 ENLACE (NO EXISTE PERO ES REFERENCIABLE)

Existen otros 10 campos de direcciones a bloques de datos. En ellos se almacena el contenido de los datos, son de indexación directa.

Podemos tener otros campos:

Indirecto simple: contiene la dirección a otro bloque de datos que a su vez contiene direcciones a bloques de datos.

%%%%%

%%%%% %%%%→ [ ]

%%%%%%%→ %%%% . . .

%%%%% %%%%

%%%%% %%%%→ [ ]

Indirecto doble (con dos niveles de indexación), indirecto triple (con tres niveles de indexación).

Estructuras de datos en UNIX

/usr/include

stat.h

filsys.h

...

Son las fuentes de programación en C. Podemos ver aquí los campos que referencian a un inodo.

struct stat {

dev_t st_dev;

ino_t st_ino;

short st_mode;

short st_nlink;

short st_uid;

short st_gid;

dev_t st_rdev;

off_t st_size;

time_t st_atime;

time_t st_mtime;

time_t st_ctime;

};


Directorios standard en UNIX versión 3

/bin

/usr/bin

Contienen los ficheros de órdenes para uso público.

PATH : $HOME /bin : /bin : /usr/bin

/tmp

/usr/tmp

Son directorios temporales. A veces funcionan como sistemas de archivo independientes. Tienen la función de ser almacenamiento temporal para procesos.

/lib

/usr/lib

Gestión o creación de librerías para programas de desarrollo de utilidades. Un gestor incorporado en UNIX es ar.

/usr

Implementa la estructura arborescente de usuarios. De él cuelgan los directorios accesibles por los usuarios.

/usr

% /man Docs del manual on-line.

% /acct Contabilidad de acceso al sistema.

% /include Definición de estructuras de datos del S.O.

% /games Juegos.

% /spool Gestión de correo y colas de impresión.

/etc

Es un directorio de mantenimiento y administración. Contiene guiones shell y ficheros que controlan y administran el sistema.

/dev

Contiene todos los ficheros que tienen características de dispositivo.

/mnt

Directorio de sistemas de archivo montados. Es la asociación de un dispositivo con un directorio lógico. Se asocia normalmente al raíz.

ARRANQUE DE UN SISTEMA UNIX

boot init getty login sh

ð ð ð

inittab gettydefs /passwd

/group

Proceso boot


Establece la ejecución de distintos procesos, siempre asociados a ficheros que sirven de diseñadores.

Proceso init

Controla el nivel de ejecución del sistema. Es el padre de todos los procesos. Normalmente es el proceso 0. Se encarga de ejecutar todas las acciones asociadas al fichero inittab. El fichero inittab se ubica en el directorio /etc y tiene el siguiente formato:

id : estado : acción : proceso

EJ:

v1 : 23 : respawn : /etc/getty/dev/vt01 9600

ls : 3 : initdefault

El primer campo es una etiqueta que individualiza cada línea.

El segundo campo corresponde a niveles de ejecución. Normalmente de forma estándar van de 0 a 4. Estos niveles están asociados a la primitiva del sistema init o /telinit. Si pongo en el prompt #init 3, se ejecutarán las acciones que tengan un 3 en el segundo campo.

El tercer campo corresponde a la acción que, a su vez, se divide en acciones.

Admite:

- off

- once

- wait

- respawn

- boot

- initdefault

Indican el modo de ejecución del proceso que les sigue.

- off: Indica a init que detenga el proceso asociado al cuarto campo.

- once: Indica a init que debe ejecutar la orden del cuarto campo sin esperar a que termine.

- wait: sirve para que init ejecute el proceso del campo cuarto esperando a que termine.

- respawn: produce en init lanzar el proceso del campo cuarto. Si no existe, no espera a que termine, si existe, no hace nada.

- boot: La acción sólo se ejecutará al arrancar el sistema. init ejecutará las líneas en las que aparezca la acción boot siempre que arranque.

- initdefault: es el estado por defecto en el que va a arrancar el sistema.

Campo cuarto: es el campo proceso. Normalmente es una orden shell que se ejecutará si la entrada estado coincide con el nivel de ejecución.

EJ: Se pretende configurar un sistema para que sea usado por alumnos de TIF, ESCUELA y FACULTAD. Habrá 5 terminales para cada tipo.

v1 : 234 : respawn : /etc/getty /dev/vt01 9600

v2 : 234 : respawn : /etc/getty /dev/vt02 9600

v3 : 234 : respawn : /etc/getty /dev/vt03 9600

v4 : 234 : respawn : /etc/getty /dev/vt04 9600

v5 : 234 : respawn : /etc/getty /dev/vt05 9600

v6 : 34 : respawn : /etc/getty /dev/vt06 9600

v7 : 34 : respawn : /etc/getty /dev/vt07 9600

v8 : 34 : respawn : /etc/getty /dev/vt08 9600


v9 : 34 : respawn : /etc/getty /dev/vt09 9600

v10 : 34 : respawn : /etc/getty /dev/vt10 9600

v11 : 4 : respawn : /etc/getty /dev/vt011 9600

v12 : 4 : respawn : /etc/getty /dev/vt012 9600

v13 : 4 : respawn : /etc/getty /dev/vt013 9600

v14 : 4 : respawn : /etc/getty /dev/vt014 9600

v15 : 4 : respawn : /etc/getty /dev/vt015 9600

#init 2 : Habilita los 5 primeros terminales enviando logins.

#init 3 : Habilita los 10 primeros terminales.

#init 4 : Habilita los 15 terminales.

Otros usos de inittab:

CERRAR Y APAGAR EL SISTEMA

- shutdown

- hatsys

- init 0. Se incluye un proceso de nivel 0 que tenga como acción un shutdown.

POSIBILIDAD DE ENTRAR EN MODO DE MANTENIMIENTO

Para entrar en modo monousuario se usa el nivel 1, con init 1.

bcheckrc (fsck)

init rc (sistema de impresión, inicializa soft de LAN, monta el sistema de archivo, ejecuta cron)

getty

init

1. Lee el nivel de ejecución por defecto (initdefault)

2. Ejecuta los niveles que tengan la acción boot y bootwait

3. Ejecuta todas las órdenes asociadas al nivel por defecto

- bcheckrc: órden equivalente a CHKDSK

- rc: sistema de impresión: gestión de colas de impresión,

área local: trasporte de datos,

sistema de archivo: asociación de un directorio lógico con un dispositivo,

cron: permite planificar y ejecutar procesos a largo plazo (procesos en modo diferido).

- getty: se ejecuta a partir de init y desde inittab. Va al fichero gettydefs, en /etc, donde se encuentra toda la descripción de protocolos de los terminales.

Presenta en pantalla un archivo identificado por /etc/issue, que sirve de login.

En el 5º campo de gettydefs existe una cadena que hace de login de conexión (login: ). Está bajo la opción respawn y espera un tiempo a que el usuario escriba su login. Si es escrito ejecuta un proceso.

Ejecución login:

init → getty → login

getty ejecuta login y busca el nº de usuario en el fichero passwd:

- si existe el usuario solicita el password.

- el fichero /etc/btmp contiene los intentos de conexión fallidos.

- el fichero /etc/utmp contiene los usuarios conectados en el día actual. Cuando ejecutamos la orden who, este archivo es consultado.

- el fichero /etc/wtmp contiene las conexiones establecidas en un tiempo determinado por el administrador.


Para conocer la estructura de estos archivios tenemos que a cada identificación de archivo le corresponderá un archivo de librería:

/etc/utmp → /usr/include/utmp.h

Después se ejecuta el primer guión shell:

init getty login sh

/bin/sh es el shell del intérprete de órdenes.

Aparece el directorio de trabajo origen. El fichero .profile es un fichero básicamente de configuración de terminal y trabajo. En el se definen las avriables de entorno, características de terminal, programas asociados (editores), etc.

En función del shell incluido en el fichero passwd, podré ejecutar distintos shells (sh, csh, ksh, rsh).

- rsh: Restringido (ventanas).

- ksh, csh: Orientados a al programación.

- sh: Shell básico.

Unix


GENERACION DE ARCHIVOS. IDENTIFICACION DE UN ARCHIVO UNIX

En UNIX el identificador de un archivo permite una máxima extensión de 14 caracteres alafanuméricos, donde mayúsculas y minúsculas son singnificativas. Los signos de puntuación no son válidos, salvo '.' y '_'. Permite el uso de comodines: '*' y '?'. Al igual que MS-DOS, UNIX incorpora los corchetes, para establecer caracteres alternantes.

EJ:

ls capitulo[123]ð% (Capítulos 1, 2 y 3)

ls capitulo[1-5]ð% (Rango del 1 al 5)

Orden ls

Referencia al inodo. Es equivalente al comando DIR de MS-DOS.

Formato:

ls -l Formato largo, presenta toda la información completa del inodo.

ls -l archivoð%

-rw-rw-rw- 1 archivo grupo 64 11:20 Sep 16

El primer carácter define el tipo de archivo. Puede ser:

-: ordinario

d: directorio

b: dispositivo de bloque

c: dispositivo orientado a carácter

p: fichero fifo (pipe)

l: enlace simbólico

Los 9 caracteres siguientes corresponden a la accesibilidad del archivo y van egrupados de 3 en 3:

Grupo 1: usuario

Grupo 2: grupo

Grupo 3: otros

Puede ser:

r: lectura

w: escritura

x: permiso de ejecución

-: denegado

El campo 11 indica el nº de enlaces. Si es un directorio informa del nº de archivos que contiene.


El campo 12 indica el usuario propietario, el 13 el grupo propietario, el 14 el tamaño del archivo en bytes (nº de octetos) y el 15 la fecha de última modificación.

A continuación vemos en el cuadro cómo afecta a ficheros ordinarios y a directorios los permisos de accesibilidad, que permitirán ejecutar unas órdenes concretas sobre ellos:

Operaciones permitidas

r

w

x

archivo ordinario

more

cat (type)

cp (copy)

vi (edit)

cp

exec

directorio

ls

rm

mv

cp

cd

# chmod +x prog ð%

Habilita el permiso de ejecución sobre el archivo prog.

Defiinición de la accesbilidad

Para establecer el permiso y acceso a archivos. Existe la primitiva chmod y tiene 2 formatos, simbólico y octal:

Notación simbólica de chmod:

u

+

r

g

-

w

o

-/=

w/x

a

=

x

u: usuario, g: grupo, o: otros, a: todos.

+: añadir permiso, -: suprimir permiso, =: asignar permiso.

r: permiso de lectura, w: permiso de escritura, x: permiso de ejecución.

Sintaxis simbólica de chmod:

EJ:

$ ls -l f1

-rw-r--r-- 1 user3 clase 37 Jul 24 11:06 f1

$ chmod g=rw, o= f1


$ ls -l f1

-rw-rw---- 1 user3 clase 37 Jul 24 11:06 f1

$ ls -l f2

-rw-rw-rw- 1 user3 clase 48 Jul 24 11:08 f2

$ chmod u+x, g=rx, o=rw f2

$ ls -l f2

-rwxr-x--- 1 user3 clase 48 Jul 24 11:08 f2

Notación octal de chmod

lectura: 4, escritura: 2, ejecución: 1.

EJ:

modo usuario grupo otros

rwxr-xr-x rwx r-x r-x

4+2+1 4+0+1 4+0+1

7 5 5

$ chmod 755 fichero

Por defecto, para directorios se establece una accesibilidad de 777 (todos los permisos activados).

Para archivos se asigna 666 (lectura y escritura para u, g y o).

Existe una variable de entorno (umask) que eprmite definir los accesos por defecto.

EJ: ¿Qué debo hacer con la variable de entorno umask para que los archivos que genere aparezcan con los permisos r, w y x para usuario y grupo y con --- para otros, al crear directorios?

umask es una variable incluida en el fichero .profile.

Ordenes a tener en cuenta:

mkdir, rmdir, ls, cd, pwd, cat, rm, mv, cp, ln, more.

find

Permite localizar o buscar archivos a través de la estructura del sistema de archivos. La búsqueda es condicional. Se pueden especificar múltiples condiciones de búsqueda.

Formato de find:

$ find directorio opciones

directorio es el origen de las búsquedas. La búsqueda se realiza recursivamente. Buscará desde el directorio indicado en todos los subdirectorios.

opciones:

- print: muestra por pantalla los archivos con sus trayectoria completa

$ find /usr -print


- perm: acompaña a una notación en formato octal. Busca desde un directorio determinado todos los archivos que tienen el acceso indicado en octal.

$ find /usr -perm 777

$ find /usr -perm 666 -print

Busca todos los archivos activos en r, w y x para u, g y o y los presenta.

- user: busca todos los archivos que pertenecen a un usuario en concreto.

$ find /usr -user pepe

$ find /usr -user pepe -print

- link n: busca todos los archivos que tengan n enlaces

$ find / -link 5 -print

-link +n (más de n enlaces)

-link -n (menos de n enlaces)

- size n: busca archivos con n bloques de datos. Cada bloque de datos son 512 bytes. También permite -size +n y -size -n.

- atime n: busca todos los archivos a los que se ha accedido en n días.

- type: tiene los parámetros clásicos del tipo de archivo.

$ find / -type opcion

opción puede ser:

- b: archivos de bloque

- c: archivos orientados a carácter

- d: directorios

- p: archivos ordinarios

- f: fifo

permite diferentes opciones con OR y AND.

- OK xxx: ejecuta interactivamente la orden shell asociada con cada archivo buscado por find.

- exec xxx: ejecuta incondicionalmente la orden shell asociada.

- name archivo: localiza determinados archivos del sistema.

$ find / -name filsys.h

localiza filsys.h mostrando la trayectoria completa.

$ find / -name "*.c"

localiza todos los archivos que terminan con la extensión '.c'

EJ: Las prácticas de un grupo de alumnos de ubican en:

/usr/alumnos/1642527

% /prog.c

% /prog.for

% /prog.pas

Se desea diseñar un directorio que parta del raíz así:

/

% /fuentes


% /c

% /for

% /pas

Hay que mover todos los fuentes en C de todos los alumnos a /fuentes/c, los de FORTRAN a /fuentes/for y los de PASCAL a /fuentes/pas.

Se comprobará si existen los directorios antes de crearlos.

Se comprobará si existen 2 ficheros de igual contenido con distinto nombre y se copiará sólo 1 de ellos.

Si 2 archivos tienen distinto contenido y el mismo nombre se renombrará uno de ellos.

Todos los archivos se cambiarán a rwxrwxrwx.

Copiaremos uno de los directorios a un disco de alta densidad MS-DOS.

EJ: Hay que hacer un programa que presente, para un directorio determinado, una tabla del siguiente modo:

$ estadistica /

ficheros ordinarios 4323

directorios 64

fifo 14

dispositivos de bloque 50

dispositivos carácter 35

enlaces 14

PROGRAMACION SHELL

El primer punto importante es la

GESTION DE ARGUMENTOS

$ utilidad fich1 fich2 fich3

$0 $1 $2 $3

El número máximo de argumentos es 10. Desde $0 hasta $9. A partir de estos argumentos podremos hacer la gestión estadística de archivos.

EJ:

$ cat > ejer01 (equivale a copy con ejer01 de MS-DOS)

echo Está ejecutándose el programa: $0

echo El valor del argumento 1 es: $1

echo El valor del argumento 2 es: $2

.

.

.

^d (equivale a ^z de MS-DOS)

$ chmod +x ejer01ð%

$ ejer01 fich1 fich2 ð%

o también


$ sh ejer01 fich1 fich2 ð%

Podemos incorporar también un editor similar a edlin, vi. Traeremos los ejercicios editados en MS-DOS y los convertiremos a UNIX:

$ mkdir guiones

$ cd guiones

$ doscp -m a:ejer01 ejer01

doscp

Sintaxis:

doscp origen destino → Copia de MS-DOS a UNIX

dosdir unidad → Contenido de la unidad en formato MS-DOS

doscat archivo → Visualiza el contenido de un archivo MS-DOS

dosls unidad → Contenido de la unidad en formato UNIX

dosmkdir → Crea directorios para unidades MS-DOS

GESTION DE ARGUMENTOS

$ utilidad fich1 fich2

$0 $1 $2 ... $n

Lenguaje C: Lenguaje PASCAL:

main (arc, argv){ ParamCount;

int argc; ParamStr(n);

char*argv[ ]

}

argc=nº argumentos

argv= cadenas separadas

En UNIX-Shell:

fich1: parámetro

"fich1 fich2": un sólo parámetro

$# contador de parámetros

$* referencia a todos los argumentos que invocamos

$$ (PIP) Identificación del proceso en ejecución

$! código de salida (exit code) de la última orden ejecutada en segundo plano (background)

$? código de salida de la última orden ejecutada en primer plano (foreground)

Modos de ejecución de un proceso

$ prog ð% (INTERACTIVO)

$ prog& ð% (DIFERIDO)

Código de retorno

Lenguaje PASCAL: MS-DOS:

{i-} ERRORLEVEL

Reset (fich1);

If (ioresult <> 0) UNIX:


then

begin $?

writeln('Error de archivo'); (Siempre en procesos interactivos)

halt(1);

end;

{i+}

Variables Shell

$0, ..., $9, $#, $$, $!, $?

Desplazamiento de argumentos

$ utilidad fich1 fich2 fich3 fich4

$0 $1 $2 $3 $4

La primitiva shift desplaza los argumentos:

$ shift

$ utilidad fich2 fich3 fich4

$0 $1 $2 $3

Shell también ofrece una copia de variables de entorno, inicializadas en la ejecución del fichero .profile.

MS-DOS → c:\>setð%

UNIX → $ setð%

EJ: En lenguaje PASCAL:

var

valor: string;

begin

...

valor:=getenv("PATH");

writeln('path=',valor);

end.

Tipos de variables de entorno en la programación shell de UNIX.

Variables asociadas al control del terminal:

$TERM Tipología del terminal, para edición.

$COLUMNS Nº de columnas.

$LINES Nº de líneas.

Variables asociadas a la gestión de directorio:

$HOME Directorio de trabajo origen.

$PATH Trayectoria de búsqueda de ejecución.

$CPATH Trayectoria de directorios sobre los que se accede (cd libros, busca libros dentro de todos los directorios indicados en CPATH)

Variables asociadas al login:

$LOGNAME Login con el que se accede al sistema.

Variables asociadas a la gestión de correo electrónico:


$MAILPATH Trayectorias de nuestro sistema de correo.

$MAIL Trayectorias de nuestro sistema de correo.

$MAILCHECK Nº de segundos de test de correo para verificar si hemos recibido.

Variables asociadas al archivo histórico:

$HISTFILE Indica la trayectoria donde se ubica el archivo histórico.

$HISTSIZE Nº máximo de órdenes permitidas en $HISTFILE.

Variables asociadas al editor:

$EDITOR Editor por defecto.

Variables asociadas al entorno shell:

$SHELL Tipo de shell.

Variables asociadas al prompt del sistema:

$PS1 Símbolo de petición de orden.

$PS2 Símbolo de petición de orden secundario.

Variables asociadas a la medición del tiempo:

$TZ Time zone, referencia la zona horaria de nuestro sistema.

Otras:

$IFS Separador de campos {:,%%, ð%}, controla las delimitaciones de estructuras de archivos en UNIX.

Otras variables de entorno en ksh (KShell)

$ERRNO código numérico de error generado por el proceso.

$PPID identificador del proceso padre del que está en ejecución.

$PWD directorio de trabajo

$SECONDS segundos que llevamos conectados a la sesión.

$RANDOM generador de valores enteros corto (16 bits) aleatorios.

init → sh → prog

Estoy en sh → padre: init

Estoy en prog → padre: sh

Variables convencionales o tipos de datos

Las variables de entorno se codifican en mayúsculas. Las variables convencionales se codifican en minúsculas. El guión Shell no tiene definiciones de tipos. UNIX surgió al mismo tiempo que el lenguaje de programación PASCAL. Todas las avriables son locales al shell que las produce:

$ x=Holað%


$ shð%

$ echo $xð%

...

^d (es como un EXIT de MS-DOS, nos salimos de la subsesión)

$ echo $x

Hola

$

Para hacer shells globales se requiere incluir la claúsula de exportación:

export HOME_PATH

Estas variables están globalizadas a todas las subsesiones.

Tratamiento de variables

variable=valor (Asignación)

Contenido y dirección

x=Hola

x: dirección

$x: contenido de x

El contenido de la variable es arbitrable por asignación interna o por la ejecución de procesos que establezcan una asignación de contenido a la variable.

n=10

n='ls -l lio'

read n (establece un valor para n desde consola)

midir='pwd'

cd $midir

EJ(72):

setcolor yellow

IFS='

'

for linea in 'cat /etc/passwd'

do

login='echo $linea | cut -f1 -d":"'

if [ $LOGNAME = $login ]

then

uid='echo $linea | cut -f3 -s":"'

gid='echo $linea | cut -f4 -d":"'

break;

fi

done

nombre_gid='grep $LOGNAME /etc/group | cut -f1 -d":"'

echo uid=$uid\($LOGNAME\) gid=$gid\($nombre_gid\)

setcolor -n

exit 0

Presenta la información del usuario.

idð%

uid=433 (Usuario) - gid=43 (Grupo)


- Asigna a la variable línea cada línea de passwd mediante un for.

- Almacena en la variable login lo obtenido en línea, cortado a partir de ':'.

- Almacena en uid el nombre del usuario.

- Almacena en gid el nombre del grupo.

El contenido asignado a una variable es siempre alfanumérico. Para evaluar expresiones desde un guión shell se recurre a la herramienta expr:

n=`expr 34+2`

n=`expr $n+1` {un contador}

(Las comillas '`' no son comillas, sino indican que se ejecuta un proceso.)

Parámetros de sustitución

${variable:-contenido}

${variable:=contenido}

EJ:

$ echo $DIR

$ echo ${DIR:-temp}

temp

echo ${DIR:=temp}

temp

echo $DIR

temp

${variable:-contenido}

Establece un valor por omisión. Si la variable no está declarada o es nula le asigna un contanido.

echo $DIR

$echo ${DIR:-temp}

temp

${variable:=contenido}

Asignación clásica.

echo ${DIR:=temp}

temp

echo $DIR

temp

ksh, csh: mantienen estructuras compuestas de datos (ARRAYS). El resto de shells sólo admiten variables simples.

Entrada/Salida (E/S)

echo

read

Entrada:


read: Asigna el contenido de la entrada estándar a las variables que tiene como argumento de forma posicional y a partir de separadores definidos (TAB,%%, ð%).

read a b c d

→ Esto es una prueba

aðEsto, bðes, cðuna, dðprueba.

Nº Argumentos > Nº Variables: El resto de la asignación lo recibe la última variable. Se define como asignación externa bloqueante por posición.

Nº Variables > Nº Argumentos: La última variable recibe el resto de los argumentos.

Salida:

echo: Es una orden básica de salida por consola, de carácter secuencial que incorpora secuencias de escape.

echo $HOME

echo Hola que tal

echo presenta siempre argumentos en la salida

echo "Hola" "que" "tal"

Secuencias de ESCAPE

\c: mantiene el cursor en la misma línea del mensaje

\b: retrocede un carácter

\n: salto de línea

\t: se produce un salto de tebulación (8 espacios)

Si incluimos secuencias de escape hemos de introducir el texto entre comillas dobles.

echo "nombre: \c"

read nombre

nombre: _

echo "\n\n\n Hola $nombre \n\n"

Hola Pepe

En lenguaje C existe algo similar:

printf(Hola \n)

EJ(37):

for NOMBRE in 'ls'

do

CONTIENE='wc -l $NOMBRE'

echo "nombre: $NOMBRE"

echo "contiene: $CONTIENE líneas"

done

Presenta nombres de archivos y nº de líneas de cada uno.

- NOMBRE va tomando como valores cada línea de ls (archivos)

- CONTIENE cuenta las líneas de cada archivo (-l: líneas)

- Escribe el nombre del archivo y su número de líneas


Las órdenes de lectura y escritura se pueden redirigir

fichero:

c1 c2 c3

cat fichero | while read c1 c2 c3

do

echo $c1

echo $c2

echo $c3

done

read asigna desde una línea cvalores o argumentos a variables.

Siempre que read lee y asigna retorna como codigo de salida 0.

Si read lee y no consigue asignar devuelve 1 (EOF).

echo $variable >> fichero, >> sirve de APPEND. Redirecciona añadiendo.

EJ(11):

IFS=":"

sed "s/$IFS$IFS/$IFS$IFS/g" < /etc/passwd | \

while read LOGIN PASSWORD UID GID GCOS DIR SHELL

do

if [ -z "$SHELL" ]

then

SHELL=/bin/sh

fi

echo"Nombre: $LOGIN, UID: $UID, GID: $GID, GCOS: $GCOS, Directorio: $DIR, Shell:$SHELL"

done

exit 0

Pasa el fichero PASSWD al bucle while.

ESTRUCTURAS DE CONTROL

Expresiones condicionales

Existen 2 variables que referencian los dos contenidos booleanos posibles:

true (0)

false (1)

Programa C:

exit (0) → Salida correcta, exit (1) → Salida con código de error

Una expresión condicional siempre va a determinar el código de retorno de la ejecución de un programa.

echo "Introduce directorio de búsqueda: \c"

read directorio

if find $directorio -print

then

echo "Tratamiento correcto \07"

else

echo "\07\07\07 Tratamiento incorrecto \n"

fi


\07 es el código ASCII en octal de BELL.

TEST

Es un evaluador de expresiones para estructuras de control.

if test $# -eq 0

then

echo "Uso: prog fich \n"

exit 1

fi

o también

if [ $# -eq 0 ]

then

echo "Uso: prog fich \n"

exit 1

fi

Devolverá true o false en función de la expresión.

Ambito de test

- evaluador de tipo de archivo

- evaluador de cadenas

- evaluador de enteros

TEST como evaluador de tipo de archivo

Sintaxis:

test opcion archivo

Opciones:

TEST devolverá true si el archivo es:

-b: especial de bloque

-c: especial de carácter

-d: directorio

-f: ordinario

-p: tubería nominada

-r: con permiso de lectura

-w: con permiso de escritura

-x: ejecutable por el usuario

-s: de longitud distinta de 0

EJ(36): Presentar en pantalla los directorios que contiene el directorio de trabajo.


for VAR in `ls`

do

if test -d $VAR

then

echo $VAR

fi

done

Es un bucle for que evalua el nombre de las entradas de directorio. Test evalua el contenido de la variable y en caso de que sea un directorio lo presenta en pantalla.

EJ(33): Llévese a un directorio "borrados" todos los archivos del directorio de trabajo ordinarios que comiencen por 'a' y elimínense del actual.

mkdir borrados

for VAR in `ls a*`

do

if test -f $VAR

then

cp ./$VAR ./borrados

rm $VAR

fi

done

Si se ejcuta el guión shell más de una vez producirá un error, ya que la primera vez se creó el directorio 'borrados'. Para resolver el problema de existencia de un directorio aplicamos el siguiente algoritmo:

if cd borrados

then

cd ..

else

mkdir borrados

fi

El ejercicio asigna cada archivo del directorio a la variable y los copia.

TEST como evaluador de cadenas

Sintaxis:

test opción cadena

Opciones:

-z: devuelve verdadero si es una cadena nula.

-n: devuelve verdadero si no es una cadena nula.

test cadena1 = cadena2 → devuelve verdadero si cadena1=cadena2

test cadena1 != cadena2 → devuelve verdadero si cadena1<>cadena2

test cadena → devuelve verdadero si cadena no es una cadena nula

TEST como evaluador de enteros

Sintaxis:

test n1 comparador n2


Comparadores:

Devuelve verdadero si se cumple

-eq: igual

-ne: distinto

-gt: mayor que

-ge: mayor o igual

-lt: menor que

-le: menor o igual

Además de estos tres tipos de gestión, test hace un tratamiento booleano residual:

!expr (equivale a la negación, NOT, devuelve true si expr es falso)

expr1 -a expr2 (comparación AND, devuelve true si expr1=true y expr2=true)

expr1 -o expr2 (comparación OR, devuelve true si expr1=true o expr2=true)

Aparte de TEST existen otros modificadores de control. Es posible establecer la ejecución prograsiva de órdenes, atendiendo a diferentes criterios:

$ ord1 && ord2

Si ord1 se ejecuta correctamente entonces ord2 se ejcutará.

$ ord1 || ord2

Aunque ord1 no se ejecute ord2 si se ejecutará.

ESTRUCTURAS DE CONTROL PROPIAMENTE DICHAS

if

if condicion

then

acciones

else

acciones

fi

EJ:

if true

then

echo Hola

fi


Desde el prompt podemos hacer:

$ if true ð%

> then ð%

> echo Hola ð%

> else ð%

> echo Adiós ð%

> fi

La programación shell de UNIX permite la implementación de ifs anidados:

if false

then

echo Hola

elif true

echo Adiós

fi

DIR=`pwd`

if [ $DIR = $HOME ]

then

echo Estoy en mi directorio

fi

$ false $ true

$ echo $? ð% $ echo $? ð%

1 0

$? es el código de retorno de la última ejecución.

false y true son dos ficheros que retornan un código:

fichero false

exit 1

fichero true

exit 0

Dentro de las sentencias de control existen unos modificadores que son:

- exit

- break

if [ $# -eq 0 ]

then

exit 6

fi

exit: provoca una terminación del proceso en ejecución y un retorno de un código al proceso padre (shell). exit se codifica en un entero corto (16 bits).

Código exit. Hay retorno de 2 valores distintos:


CODIGO SEÑAL

CODIGO EXIT

ð%%8 bits%%→ ð%8 bits%→

[A] 153 Antes de finalizar el proceso A se ejecuta KILL -9 153.

ð En lugar de enviar 0 se envia 9, el código señal, que es el

exit 0 octeto más significativo.

break: es una ruptura de control de bucle

while true

do

echo "Número: \c"

read numero

if test -n numero

then

break

else

...

fi

done

Si se entra en break se sale del while.

for

for variable in lista

do

acciones

done

for var in 1 2 3 4 5

do

echo $var

done

Una de las aplicaciones más utilizadas del bucle for es la ejecución de procesos.

for var in `find / -name "*.c" -print`

do

echo $var

done

Presenta las trayectorias de los archivos encontrados.

Excepciones:

for a in *

do

echo $a

done

Lista el contenido del directorio

for a in $*

do

echo $a

done


Presenta cada uno de los argumentos

for a in $

do

echo $a

done

Gestiona los argumentos de la línea de órdenes

Como ejemplo de la gestión de for tenemos el siguiente ejercicio:

EJ(50): Programa que gestione subdirectorios para programas fuente de C, PASCAL y FORTRAN.

if test ! -d prog_c

then

mkdir prog_c

fi

if test ! -d prog_for

then

mkdir prog_for

fi

if test ! -d prog_pas

then

mkdir prog_pas

fi

for var in `ls`

do

case $VAR in

*.c) directorio=./prog_c;;

*.f) directorio= ./prog_for;;

*.p) directorio=./prog_pas;;

*)continue;;

esac

encontrado=no

for l in `ls $directorio`

do

if cmp $VAR $directorio/$l > /dev/null

then

encontrado=si

break

fi

done

if [ $encontrado=no ]

then

if test -a $directorio/$VAR

then

cp $VAR $directorio/$$_$VAR

else

cp $VAR $directorio

fi

fi

done

exit 0


En caso de que existan los directorios no serán creados.

case (Estructura selectiva múltiple)

case $var in

et1) acciones;;

et2) acciones;;

et3) acciones;;

esac

$var puede ser un tipo complejo (cadena) o simple (entero).

Las etiquetas no deben repetirse.

Cada etiqueta debe siempre terminar con ;; (ruptura de estructura de control)

Las etiquetas admiten comodines.

case $var in

et1) acciones;;

et2) acciones;;

*) gestión_de_errores;;

esac

El ejemplo 50 visto anteriormente utiliza *) continue;; para no gestionar errores.

while (Bucle pretest)

Evalua una condición. Si es cierta ejecuta las sentencias.

while condicion

do

acciones

done

until (Bucle postest)

Se ejecutan las acciones hasta que la condición sea cierta.

until condicion

do

acciones

done

Archivos FIFO

Sincronización de procesos:

1. Creación: Usaremos mknod. Crea un nodo que se corresponde con un archivo especial.

Para crearlo:

$ cd /etc

$ mknod $HOME/fifo p


$ ls -l

pfw-rw-rw-

Características de los archivos FIFO:

- Tienen longitud 0

- Sincronizan procesos estableciendo bloqueo en apertura y en lectura/escritura

Si después de crear un archivo FIFO hacemos:

$ ls -lia > fifo

A B

ls → [fifo] → cat $ cat fifo

Productor Consumidor

El archivo FIFO que es abierto para escritura por un proceso, necesita que otro proceso lo abra para lectura. El terminal queda bloqueado hasta que se ejecute la orden en modo diferido.

Para no establecer un bloqueo recurrimos a lo siguiente:

$ ls -lia > fifo&

[543]

$

$ cat fifoð%

(Se abre FIFO para lectura) se bloquea en apertura y se desbloquea en lectura.

$ cat fifo no se podrá ejecutar mientras fifo no tenga información.

EJ:

$ cd /etc

$ mknod $HOME/fifo p

$ cd $HOME

$ ls -lia > fifo

$ ls -lia > fifo& (Productor)

[154]

$ ps -ef | grep 154

$ cat fifo (Consumidor) {Aunque cambiemos el orden de productor y consumidor, este siempre acaba el último)

Escribo el contenido de fifo en pantalla. Se abre para lectura y se bloquea hasta que el proceso productor le suministre información.

fifo sólo almacena información en los 10 bloques de datos de indexación directa.

Un proceso productor que genere mucha información a un archivo fifo puede llegar a ocupar los 10 bloques de datos de indexación directa. En este caso el proceso productor se bloqueará en escritura hasta que un proceso consumidor le libere de información.

Editor vi

Ordenes básicas:

vi fichero


i: inserción

[ESC]: modo edición/comando

A: añadir

x: borrar carácter

dd: borrar línea

:wq!: grabar y salir

r: reemplazar carácter

R: reemplazar cadena

MODULOS

La programación shell no permite casi el diseño modular aunque es posible implementarlo. La sintaxis de función es:

identificador ( ) {

orden(es)

}

No se admiten pasos de variables por valor ni referencia.

En KShell las funciones van precedidas por la palabra reservada function antes de la estructura anterior.

EJ: Crear un guión shell para la gestión de un archivo con nombres y números de teléfono, que permita dar altas, bajas, modificaciones y consultas.

altas( ) {

echo "Nombre: \c"

read nombre

echo "Teléfono: \c"

read telefono

echo "$nombre : $telefono" >> datos.dat

}

consulta( ) {

echo "Nombre: \c"

read nombre

for linea in `cat datos.dat`

do

n=`echo $linea | cut -f1 -d ":"`

if test $nombre = $u

then

echo "Nombre: $nombre"

telefono=`echo $linea | cut -f2 -d ":"`

echo "Teléfono: $telefono"

break

fi

done

}

# La función de consulta se puede resumir también del siguiente modo:

consulta( ) {

echo "Nombre: \c"


read nombre

cat datos.dat | grep $nombre

}

borrar( ) {

echo "Nombre: \c"

read nombre

encontrado=false

for i in `cat datos.dat`

do

name=`echo $i | cut -f1 -d ":"`

if test $name != $nombre

then

echo $i >> temp$$

else

encontrado=true

fi

done

if test | $encontrado

then

echo "\07 No existe \n\n"

rm temp$$

else

rm datos.dat

mv temp$$ datos.dat

fi

}

# Menú principal

while true

do

clear

echo "1 Altas"

echo "2 Bajas"

echo "3 Consultas"

echo "4 Salir"

echo "Opción: \c"

read opcion

case $opcion in

1) altas;;

2) bajas;;

3) consulta;;

4) exit 0;;

*) echo Error;;

esac

done

Ejercicios propuestos:


EJ: Implementar la gestión de 2 archivos relacionados:

ARCHIVO 1 ARCHIVO 2

nº expediente nombre alumno nº habitación nº teléfono

-------------------- ----------------------- ------------------- ----------------

-------------------- ----------------------- ------------------- ----------------

-------------------- ----------------------- → ------------------- ----------------

-------------------- ----------------------- ------------------- ----------------

-------------------- ----------------------- ------------------- ----------------

Altas, bajas, modificaciones y consultas. No se admiten claves repetidas.

EJ: Hacer una función recursiva (función factorial).

Archivos de tipo directorio

ls

En la estructura de directorio hay dos tipos:

- La implementada por UNIX SYSTEM V

- La implementada por UNIX 4.3 BSD

La gestión de directorios responde en cada una a diferentes notaciones.

Estructuras de directorio en UNIX

SYSTEM V

struct direct {

ino_t d_inode;

char d_name [DIRSIZ];

};

Un directorio contiene un bloque de datos con los nombres de archivo e inodos.

67

.

70

..

435

fich1

423

fich2

602

fich3

ls recorre el directorio y cuando encuentra el número de inodo se dirige a la lista de inodos y obtiene la información de un fichero determinado.

SYSTEM V permite identificar un archivo con un máximo de 14 caracteres.

La estructura del directorio se alberga en dir.h.


4.3 BSD ('Berkley')

struct dirent {

ino_t d_ino;

short d_reclen;

short d_namelen;

char d_name[_MAXNAMLEN+1];

};

Berkley permite construir identificadores de archivo de longitud variable.

El registro contiene:

- nº de inodo

- longitud de registro (reclen es el offset y el desplazamiento)

- nº de caracteres

- identificador del archivo

También se crearon primitivas de funciones de gestión para este tipo de archivos, las cuales no existían en SYSTEM V.

En dirent.h está la estructura dirent.

Se implementan las siguientes primitivas:

opendir

rewinddir

readdir

closedir

seekdir

con la posibilidad de usarlas desde C para gestionar la estructura de directorios en 4.3 BSD.

A nivel de usuario no es posible saber qué sistema se usa, pero a la hora de programar es fundamental diferenciarlo.

Ejercicios propuestos:

EJ:

/

% /DOS

%/BORLANDC

%/BIN

%/INCLUDE

Diseñar la orden TREE de DOS con el sistema de archivo de directorio. Dependiendo del nivel en el que nos encontremos habrémos de tabular o retroceder.


ARCHIVOS DE DISPOSITIVO

- Orientados a carácter (terminales, unidades de cinta)

- Orientados a bloque (soportes magnéticos, discos duros)

Estudiaremos éste último.

Archivos de dispositivo orientados a bloque

Trabajan con el concepto de bloque lógico. Las técnicas de indexación están ceñidas a la unidad (512 bytes, normalmente). Usarán un buffer caché (área intermedia de E/S). Los archivos de dispositivo están ubicados en el directorio /dev:

$ ls -al /dev/hd*

brw - - - - - - - 2 sysinfo sysinfo 1, 0 Mar 14 1989 /dev/hd00

sysinfo en usuario y grupo indican que es propiedad del sistema.

1, 0: Son el nº mayor y nº menor que funcionan como índices numéricos referenciando a una tabla interna de Kernel que contiene las direcciones de memoria donde se localiza el driver de gestión de E/S de dispositivos.

Identificación de los dispositivos de bloque

- Identificación básica de 2 ó 3 caracteres.

- Identificación numérica (nº disco, partición, cilindros, pistas, sectores/pista) referenciando a un valor cuantitativo de la densidad de información admitida por el dispositivo.

Asociación del sistema de archivos a un dispositivo de bloque

En los archivos:

/etc/checklist (ASCII)

/etc/mnttab (BINARIO)

Con la orden mount.

$ mount

/ /dev/fsk/0s1 4785 block 4327 i-node

mnttab y checklist son archivos que asociarán el sistema de archivos con dispositivos de bloque.

Con la orden mount aparece:

- id directorio

- id dispositivo de bloque

Estructura informativa de un dispositivo de bloque

[boot][superbloque][lista_de_inodos][datos][swap]

512

Superbloque: su información reside en un archivo ubicado en el directorio:


/usr/include/sys/filsys.h (En SYSTEM V)

/usr/include/sys/fs.h (En HP UNIX)

filsys es un registro que nos dice cuál es la estructura exacta del superbloque. Contiene el nº de inodos y bloques de datos del sistema de archivo. Tiene un campo con la última fecha de actualización de superbloque realizada por Kernel (que es el único que puede modificarlo).

sync y update son dos procesos que sincronizan y actualizan el suoperbloque con la lista de inodos.

Además existen otros campos:

- nº de bloques libres

- nº de inodos

- Campos de bloqueo (sincronización de Lectura/Escritura para Kernel)

- Campo indicador de cierre incorrecto de la sesión anterior

- Campo de referencia al modo de acceso al sistema de archivo (Lectura o Lectura/Escritura)

- nº mágico, es el nº de la versión de UNIX en uso. Es un entero largo. Sirve para saber el tamaño de bloque del sistema de archivo (512, 1024, 2048)

- Nombre del sistema de archivo y versión del S.O.

El superbloque almacena toda la información relacionada con el sistema de archivo. Para situarnos en el superbloque:

lseek (archivo, 512, 0) desde C en filsys.h

Lista de inodos

Almacenamiento en el dispositivo de bloque. En el archivo /usr/include/sys/ino.h aparece la estructura del inodo. Se almacena:

- 40 octetos de indexación (cada información en 3 octetos).

En struct d_inode tenemos la esencia básica de almacenamiento en un dispositivo de bloque.

GESTION DE CORREO

El subsistema de correo de UNIX proporciona varias órdenes de gestión:

MAIL, MAILX

WALL

WRITE

NEWS

El subsistema de correo se divide en:

- Gestión de archivo (MAIL, MAILX)

- Gestión de terminal (WALL, WRITE, órdenes para enviar desde un terminal a otro también conectado)

También se pueden enviar mensajes de forma diferida, sin que esté conectado el receptor.

El subsistema de correo dispone de una estructura de directorios propia:

/usr/spool/mail/$LOGNAME

/usr/spool/mail/pepe será el archivo con todo el correo del usuario pepe.

MAIL: es un programa que gestiona archivos de correo.


WALL: órden de gestión de correo orientado a terminal. Permite enviar un mensaje a todos los usuarios conectados. La lista de usuarios está en utmp y WALL supervisa dicha lista para averiguar que usuarios están conectados. Envía un mensaje que acaba con ^d y que será supervisado por el administrador. El tipo de correo que se enviará desde WALL será general, por ejemplo aviso de que se cerrará el sistema. No es posible proteger nuestro terminal contra correo producido por WALL.

WRITE: Permite la comunicación con otro usuario conectado. Por ejemplo: WRITE uft21 tty02

TALK: divide el terminal en 2 áreas, una de emisión y otra de recepción. Tan sólo difiere de WRITE en la presentación. La filosofía es la misma, se trata de gestionar un archivo secuencial.

MESG: Pemite activar o desactivar la recepción de mensajes. MESG N desactiva, MESG Y activa.

Con chmod go-w tty03 desactivaríamos el acceso al terminal tty03, causando el mismo efecto que tecleando MESG N en el terminal tty03.

SISTEMAS DE CORREO ORIENTADOS A ARCHIVO

/etc/motd es un archivo que corresponde a las noticias diarias que cualquier usuario de la red que se conecte debe conocer. Este archivo es supervisado por cada .profile de conexión de cada usuario.

NEWS presenta las noticias del sistema que se encuentran disponibles. Esta utilidad visualiza el contenido de /usr/news, varios ficheros con formato ASCII, que se presentarán en función de su asignación. En el fichero .profile existirán sentencias del tipo:

if [ -f /usr/news ]

then

news -n

fi

Visualizará los nombres de los archivos sin modtrar su contenido. Sólo presenta las noticias actuales, no las ya pasadas de fecha. Hay un archivo que siempre referencia a la última fecha de consulta de news. Este es un fichero oculto, .news_time y contiene la última fecha de consulta de las news.

Ej. Diseñar un programa que presente y gestione noticias en el directorio /usr/news, controlando la fecha de última consulta.

Pasos a seguir:

1) Presentar nombres de fichero

2) Presentar contenido de los ficheros

Según Kernighan:

# versión 1.0 news

for i in `ls -t /usr/news/* ./.news_time`

do

case $i in

*/.news_time) break ;;

*) echo news: $i ;;

esac

done

touch .news_time

touch es una utilidad suministrada con UNIX que crea un archivo con la fecha actual.

# versión 2.0 news

IFS='


'

for i in `ls -t /usr/news/* $HOME/.news_time 2 > /dev/null'

do

case $i in

*'not found') ;;

*/.news_time) break ;;

*) echo news: $i ;;

esac

done

touch .news_time

# versión 3.0 news

IFS='

'

for i in `ls -t /usr/news/* $HOME/.news_time 2 > /dev/null'

do

case $i in

*'not found') ;;

*/.news_time) break ;;

*) echo news: $i

cat $i ;;

esac

done

touch .news_time

MAIL/MAILX

MAIL permite enviar y gestionar correo recibido. Incluye la gestión de control remoto (a otro sistema UNIX conectado). El envío de correo responde básicamente a los siguientes criterios:

$ mail usuario(s) ð%

A partir de aquí se escribe un fichero y con ^d finalizamos. El archivo es enviado.

También permite la redirección:

$ mail andres < memoria ð%

o el uso de tuberías:

$ ls | mail andres ð%

El usuario andres recibe el resultado de ls en su terminal.

Gestión de correo recibido:

mail permite verificar si existe correo con el parámetro e:

if mail -e

then

echo Tiene correo

fi

mail -e devuelve 0 si hay correo nuevo o 1 si no hay.

$ mail ð%


Devuelve un listado de los mensajes recibidos:

- emisor (cabecera)

- fecha de emisión

- tamaño del mensaje

Ordenes para la gestión del correo:

$ mail ð%

#_

+, ð%, ð, n salta al siguiente mensaje

d, dp marca para borrar el mensaje recién leído y salta al siguiente

dn marca para borrar el mensaje n, sin saltar al siguiente

dq marca para borrar el mensaje actual y sale de mail

h presenta una ventana de cabeceras, incluyendo el mensaje en curso

ha presenta la cabecera de todos los mensajes

hn presenta la cabecera de un mensaje determinado

hd presenta la cabecera de los mensajes marcados para borrar

num salta al mensaje num

p presenta el mensaje actual

q, ^d guarda en el archivo buzón los mensajes que no están marcados para borrar y sale

r [usuario(s)] responde a la persona que envió el mensaje en curso y permite enviar copias a otros

usuarios, si se especifican. Este mensaje (reply) es marcado para borrar

s [fichero] vuelca el mensaje en curso a un archivo y lo marca para borrar

u [num] recupera un mensaje marcado para borrar de número num

w [fichero] vuelca el mensaje en curso a un archivo, omitiendo la cabecera y lo marca para borrar

x termina la ejecución de mail sin salvar los cambios

y hace lo mismo que s

! orden permite ejecutar una orden de UNIX

? presenta la ayuda de mail

Correo no enviable:

Si el usuario no existe:

a) se interrumpirá la creación del mensaje, presentando un error

b) el correo será devuelto y almacenado en un archivo de identificador dead.letter

Envío de correo a usuarios remotos:

Todo sistema UNIX con UUCP obedece a:

Verificación de los sistemas conectados:

$ uname -n, presenta el nombre de cada sistema UNIX de la red. Obtine la lista de sistemas activos para comunicación mediante UUCP.

Para saber si un sistema está conectado a la red UUCP:


$ uname | grep nombre, presenta la información del sistema indicado si éste está conectado a la red.

Habrá que establecer una trayectoria de comunicación para enviar a ese sistema:

$ mail nombre ! subnombre ð%

Permite de este modo establecer comunicación con un sistema en concreto y a partir de ahí con un usuario de dicho sistema.

MAILX abarca la misma filosofía incorporando muchas más posibilidades de gestión y detalle en la descripción de los mensajes (tamaño, nº de palabras, caracteres, buzón origen, ayuda extendida,...) y un fichero de configuración que permite incorporar cualquier editor de mensajes (MAIL sólo permite ed).

Estructura de MAILX:

$ mailx ð%

orden [lista de mensajes] [argumentos]

- orden similar a MAIL

headers (h)

help (?)

mail (m)

reply (r)

save (s)

undelete (u)

visual (v)

write (w)

delete

dp

#

!

=

Se acerca a una gestión de correo relacional.

- lista de mensajes

n nº de mensaje

ð mensaje actual

^ último mensaje

$ primer mensaje

n-m

usuario

- argumentos

Los argumentos se corresponderán con la posibilidad que ofrezca cada órden:


- fichero(s)

- usuario(s)

Ej. Gestionar un array desde un guión shell:

a) Almacenar aleatoriamente valores numéricos en dicho array sin repeticiones.

b) Ordenar el array.

c) Presentar en pantalla cada valor numérico con un color diferente.

GESTION DE IMPRESION

El subsistema de gestión de impresión en UNIX está compuesto por:

- Gestor de impresión (lpsched)

- Sistema de archivo de impresión

El gestor es un proceso que se ejecuta en modo diferido o background de forma contínua, para controlar la cola de impresión.

En MS-DOS existe el programa print, un programa residente que permanece activo en background. En UNIX el gestor de impresión se mantiene activo durante toda la sesión. Se encarga de:

- gestionar la cola de impresión

- gestionar los recursos y dispositivos de impresión

Es un proceso demonio que no está asociado a ningún terminal (tty).

Para saber si el gestor de impresión está activo usaremos la orden

$ ps -ef

que presenta el estado de los procesos en ejecución.

A partir de ps obtendremos las carecterísticas de cada proceso que se esté ejecutando. En el caso de lpsched:

UID PID PPID tty command

lp 69 1 ? lpsched

- Identificación de usuario del proceso (UID):

En el fichero /etc/passwd hay una entrada para usuario, la entrada lp, que es la entrada de usuario para todos los procesos relacionados con la gestión de impresión.

- Nº de proceso (PID):

Es un valor asignado por Kernel. Init se encarga de establecer la ejecución de los demonios del gestor de impresión.

init getty login

% rc


El valor que se le asigne será siempre un nº muy bajo, ya que procede del proceso init, que es el proceso de valor 1.

- Nº del proceso padre (PPID):

Siempre es 1, que indica que el proceso padre de lpsched es init.

- tty:

? indica que no está asociado a ningún terminal. Este proceso no morirá cuando un usuario cierre una sesión en su terminal.

Otro forma de saber si lpsched está activo es ejecutando la orden

$ lpstat -r

así sabremos si lpsched se está, o no, ejecutando.

Cuando tengamos que dar de alta una impresora, modificar una cola de impresión o efectuar cualquier actualización estructural de impresión tendremos que desconectar previamente el gestor de impresión.

UNIX implementa una estructura de directorios con información sobre el gestor de impresión:

(1) /usr/bin

lp

lpstat

lpinfo

lpsetup

enable

disable

accept

reject

son las órdenes de uso público.

(2) /usr/lib

lpsched

lpschut

lpadmin

lpmove

contiene órdenes exclusivas y específicas para el uso de la administración (alta de impresoras, activación y desactivación de trabajos, etc.).

(3) /usr/spool/lp

FIFO

SCHEDLOCK

log

oldlog

seqfile

default

contiene los ficheros de configuración del subsistema de impresión y ficheros temporales a los trabajos que se están imprimiendo.

FIFO: es un archivo de comunicación y sincronización entre la orden lp y lpsched (gestor de impresión).


SCHEDLOCK: es un archivo de bloqueo, utilizado por el gestor de impresión para evitar la múltiple autoejecución. Impide que el gestor de impresión se ejecute más de una vez.

lod y oldlog: contienen registros de los trabajos que han sido impresos y de los que se están imprimiendo.

seqfile: contiene el valor numérico de identificación de la petición actual de impresión, de modo que lpsched sabe cuántos archivos esperan para impresión.

default: contiene la identificación de la impresora por defecto.

/usr/spool/lp/model

Es un directorio de modelos que contiene las impresoras que hay en el mercado por marca, modelo y tipo de conexión (serie o paralelo). Cada modelo es un guión shell que relacionará la orden de impresión de usuario (lp) con el dispositivo físico que representa la impresora. Sincronizará y representará la información para determinado dispositivo físico.

/usr/spool/lp/requests

Contiene subdirectorios, uno por cada impresora establecida, donde se ubicarán los trabajos que le pertenezcan a cada impresora.

INSTALACION DE UNA IMPRESORA

Tipo de impresora: Las impresoras actuales permiten ambos tipos de conexión (serie y paralelo). Para establecer el protocolo de comunicación se usará un sistema hardware (jumpers) o software (si el periférico lo permite).

Interface de conexión: Es la tarjeta con los puertos asignados. Seguiremos la siguiente tabla para identificar el puerto con el dispositivo:

LPT1

/dev/lp

/dev/lp1

PARALELO

LPT2

/dev/lp2

PARALELO

LPT3

/dev/lp3

PARALELO

LPT4

/dev/lp4

PARALELO

COM1

/dev/tty00

SERIE

COM2

/dev/tty01

SERIE

COM3

/dev/tty02

SERIE

Pasos a seguir:

a) Comprobar la conexión:

$ cat prueba > /dev/lp

semejante a copy prueba prn: de MS-DOS.

b) Comprobar el tipo de impresora:

b.1) definir el modelo de impresora

b.2) usar un modelo estándar si no está disponible el nuestro

b.3) en caso de fallar los dos pasos anteriores crear un guión shell


En UNIX habrá una cover-page por cada impresión que hagamos. En el guión shell podemos ver su estructura.

c) Desactivar el gestor de impresión:

Será necesario entrar en el sistema como root. Usaremos /usr/lib/lpschut para desactitvar el gestor de impresión o también podemos optar por enviar una señal con kill -9 ó -15.

d) Dar de alta la impresora:

/usr/lib/lpadmin -p laser -v /dev/lp -i /usr/spool/lp/model/hpjet

Con los argumentos identificamos la impresora a instalar:

-p laser: asigna laser como identificación de la impresora a efectos de tratamiento

-v /dev/lp: es el puerto de dispositivo hacia donde se dirige la impresión

-i /...: indica el modelo de inserción para establecer el protocolo

e) Habilitar el gestor de impresión:

/usr/lib/lpsched. A partir de este momento ya podremos imprimir.

f) Habilitar la impresora:

Lo haremos mediante la orden enable que se ubica en el directorio /usr/bin. Ejemplo:

enable identificador → enable laser

g) Activar la impresora:

De este modo será capaz de recibir trabajos. Se hará mediante la orden accept del directorio /usr/bin. Ejemplo:

accept identificador → accept laser

IMPRESION

Existe una orden para solicitar un permiso de impresión: lp.

Sintaxis:

lp [opciones] [fichero(s)]

Si omitimos los parámetros imprimirá la entrada estándar.

Opciones:

-d: permite especificar una impresora en particular (-d identificador).

-m: notifica al usuario la impresión mediante el envío de un mensaje por correo electrónico una vez finalizada la impresión del archivo.

-ncopias: establece el número de copias a imprimir.

-ttítulo: permite presentar un título para el informe a imprimir.

-w: muestra un mensaje al finalizar el trabajo de impresión.


Cómo evitar la impresión de la cover-page

En el archivo /etc/default/lpd se almacena la variable BANNERS. Si la ponemos a 0 no imprimirá la cover-page.

Estado de impresión

La orden para conocer el estado de impresión es lpstat.

lpstat presenta información sobre las peticiones de impresión y sobre las impresoras.

Sintaxis:

lpstat [opciones] [identificación_de_peticiones]

Opciones:

-a: muestra en pantalla cuáles de los dispositivos listados aceptan o no peticiones de impresión.

-d: muestra en pantalla el nombre de la impresora por defecto.

-r: presenta el estado del controlador de impresión (lpcheck).

-t: presenta toda la información acerca del estado de las impresoras.

Control de impresión

Si se detectan anomalías en una impresora tendremos que desactivar el gestor de impresión para suspender los trabajos en espera. Usaremos /usr/lib/lpschut y cancel identificativo para cancelar la impresora en cuestión.

Si queremos definir el error que ha producido la anomalía para que todos los usuarios conozcan el porqué de la desactivación del dispositivo usaremos la orden reject. Por ejemplo: /usr/lib/reject -r 'laser sin papel' identificador.

Tendremos que mover todos los trabajos de dicha impresora hacia otro dispositivo si queremos seguir imprimiendo con /usr/lib/lpmove identificador nuevo_identificador.

Una vez solucionado el error habilitaremos el gestor.

Cómo establecer una impresora por defecto

Usaremos /usr/lib/lpadmin -d identificador

2. PROCESOS

El sistema operativo UNIX distingue programas y procesos.

Programa: secuencia lógica de instrucciones codificadas en un lenguaje determinado, que se ejecutan cargándose en memoria. Un programa puede contener 1 ó varios procesos.

Ficheros ejecutables en UNIX:

cc {compilación} cc fuente.c

ð ð

ld {enlace (linking)} a.out

ð

a.out {ficheo ejecutable}

Formato de los ficheros ejecutables en UNIX (a.out):


a.out.h es un archivo de librería que contiene las estructuras de datos que componen un fichero ejecutable.

man a.outð% nos devuelve la información proporcionada por el manual on-line que explica lo que es un ejecutable.

Areas de un fichero ejecutable:

1. Header: encabezamiento, estructura de datos que proporciona, mediante un número, la dirección donde se carga el proceso. También indica los tamaños que conforman un archivo ejecutable; el segmento de datos, segmento de código y tabla de símbolos.

2. Segmento de datos inicializados: variables globales y variables estáticas. Almacena todas las variables a un valor definido antes de la ejecución, en este área (BSS).

3. Segmento de código: compuesta por todas las instrucciones del algoritmo en código máquina.

4. Tabla de símbolos: identificadores externos que utiliza el programa.

Ficheros ejecutables interpretados:

Ficheros que interpreta y ejecuta el shell, siendo previamente analizados lexicográficamente (similar a un intérprete de órdenes como QuickBasic). Un ejemplo son los guiones-shell (ASCII).

Cuando un guión shell o un fichero ejecutable es cargado en memoria, se convierte en procesos.

Para generar procesos dentro de ficheros ejecutables se utiliza:

fork ( ): genera 2 procesos que se ejecutan concurrentemente.

Ej:

#include <stdio.h>

main ( )

{

int pid;

pid=fork( );

if (pid>0)

printf ("Soy el proceso padre (%d) \n", getpid( ));

else

printf ("Soy el proceso hijo (%d) \n", getpid( ));

}

Cuando se generan 2 procesos, ambos tienen las mismas instrucciones y se ejecutan concurrentemente.

fork dará valor 0 al proceso hijo y el pid del proceso hijo al proceso padre (un valor entero positivo).

A partir de fork el contador de programa ejecuta las instrucciones en 2 copias exactas.

Información que hereda el proceso hijo del proceso padre:

fork: genera la creación de un nuevo proceso.

El proceso hijo hereda:

- variables de entorno

- argumentos que recibe el programa

- sistema de máscara (umask) o de protección de accesos

- directorios de trabajo y raíz

- gestión de señales e interrupciones (kill y trap)


- valor de la prioridad (padre e hijo se ejecutan con la misma (nice))

- identificación del terminal

- identificación de grupo del proceso

- segmentos de código y datos

Cuando un programa es cargado en memoria, en UNIX, se copian las áreas del ejecutable, construyendo:

Segemento de datos BSS

------------

Segmento de código TEXT

------------

Segmento de pila STACK

------------

Area dinámica de datos HEAP

El segmento de pila está compuesto por 2 áreas:

Area de usuario: requerida para las funciones de usuario.

Area de kernel: guarda una pila por cada proceso, donde se almacenará el contexto del proceso en ejecución, antes de cada llamada (multiproceso).

El area dinámica de datos gestiona los datos de modo dinámico y no estático (heap=montículo).

Ej:

guion

orden1 > archivo1& → equivale a un fork ( );

orden2 > archivo2& → equivale a un fork ( );

Sincronización de procesos a partir de fork ( );

fork ( );

A B

orden1 > archivo1&

orden2 > archivo2&

wait

sort archivo1 archivo2

wait es una sentencia de sincronización. Desempeña una función de espera hasta que terminen los procesos hijos asociados. Esta sentencia suspende la ejecución de sentencias y espera hasta que el/los proceso/s hijo/s terminen. Entonces el proceso padre continúa su ejecución.

Estados de un proceso:

EJECUCION USUARIO

llamada retorno

al sistema

retorno de interrupción

EJECUCION

dormir KERNEL orden de ejecución


dada por el planificador

DORMIDO LISTO PARA

despertar EJECUCION

Estados:

1 EJECUCION USUARIO: el programa ejecuta las instrucciones de un algoritmo codificado por un usuario.

2 EJECUCION KERNEL O SUPERVISOR: el programa hace una llamada al sistema; gestión de archivos (open, read, write, ...), gestión de procesos (fork ( ), exec), etc.

3 LISTO PARA EJECUCION: el proceso no se ejecuta, pero está listo para ser ejecutado. Por ejemplo, cuando un proceso necesita memoria y la paginación establecida no le puede servir memoria suficiente, cuando se libere memoria, el planificador lo pasará a ejecución.

4 DORMIDO: estado que está determinado por operaciones de E/S. Por ejemplo, una operación de lectura, hasta que no llegue una señal que libere al proceso de la E/S, el proceso no saldrá de este estado.

Tipos de proceso:

Pueden haber sido generados mediante 2 herramientas:

- fork ( )

- exec

fork ( ) duplica el contexto del proceso (segmentos de datos y código).

exec realiza un solapamiento del segmento de código.

Ej:

guion

exec date

echo "Esto nunca llegará a ejecutarse"

Este guión shell ejecuta date y solapa el segmento de código de date sobre el proceso principal, que es el guión shell. Aparecerá la fecha, pero la línea de echo nunca aparecerá, ya que habrá sido sobreescrita por el segmento de código de date.

Ej: Hacer dos guiones shell, uno principal y otro secundario subordinado:

Salida:

iiiih! padre

ooooh! hijo

Estado de los procesos en memoria (ps):

La orden ps presenta información sobre los procesos activos en memoria.


$ ps -l

F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME COMD

10 5 4392 17118 3211 0 30 20 1c40368 149 10d924 22:00:00 term/41 0:01 vi

Campos:

F: referencia indicadores o flags que establecen las características del proceso. Los flags hexadecimales más frecuentes son:

00: proceso terminado

01: proceso del sistema (getty, init, planificador de tareas)

02: proceso en traza y depuración

08: proceso en memoria principal

10: proceso bloqueado

S: indica el estado del proceso. Puede ser:

O: proceso en ejecución

S: proceso dormido

R: proceso en cola de ejecución

I: proceso inactivo en creación

Z: proceso zombi

T: proceso detenido en modo de traza

X: proceso en espera de liberación de memoria

UID: indica el nº de identificación de usuario propietario del proceso activo en memoria en ejecución

PID: indica el nº de identificación del proceso (asignado por Kernel)

PPID: indica el nº de identificación del proceso padre

C: asociado a la planificación del gestor de procesos. Se refiere a las CPUs y FPUs presentes en el sistema

PRI: valor de la prioridad de ejecución del proceso. A mayor valor le corresponderá peor prioridad

NI: valor nice de prioridad. Se establece para calcular la prioridad (PRI). Es un valor entero, por defecto se asigna 20 al proceso

ADDR: dirección física de memoria donde se almacena el proceso. Si el proceso está volcado en memoria externa la dirección toma el valor de 0

SZ: tamaño en páginas del proceso en memoria

WCHAN: dirección de espera de un evento. Es una dirección de memoria donde se establece la gestión de una señal

STIME: hora de inicio de ejecución, proporcionada en el formato hh:mm:ss

TTY: terminal asociado al proceso. Si es un proceso demonio, no asociado a terminal, vale ?

TIME: tiempo de ejecución acumulado hasta el momento

COMD: orden asociada al proceso

Opciones:

ps -ef proporciona información completa


Ej:

ps -ef | grep pepe

Presenta las relaciones asociadas al patrón de búsqueda (pepe) en formato largo.

Ej: Realizar un guión shell que nos permita presentar las dependencias de los procesos.

148

149

183

260

264

268

Se intentará simular recursividad. Este guión shell ejecutará una función denominada proceso:

proceso ( )

{

IFS='

'

for i in `ps -ef | tail +2`

do

if [ $2 -lt 14 ]

then

IFS=' '

ppid='echo $i | cut -f3 -d" "'

if [ $ppid = $1 ]

then

hijo='echo $o | cut -f2 -d" "'

tabular=$2

until [ $tabular = 0 ]

do

echo " \c"

tabular='expr $tabular -1`

done

echo "-- $hijo"

tabular=`expr $2 +2`

proceso $hijo $tabular&

wait

fi

fi

done

}

# programa principal

proceso 1 0

exit 0

Ejercicios propuestos:

Ej: Guión shell que se ejecute cada 5 minutos y que calcule el nº de páginas de los procesos que están activos en memoria. Si este nº excede un valor constante determinado, eliminará los procesos de menor prioridad (aquellos con menor valor en el campo 'PRI' de ps).

Ej: Codifíquese un guón shell que elimine los procesos de aquellos usuarios cuya clave de acceso eté caducada.


Comunicación entre procesos

Niveles de sincronización:

FIFO (tuberías):

Ej: ls | sort

Proceso a: ls

Proceso b: sprt

La tubería (|) sincroniza ambos procesos. El proceso b no se ejecuta mientras a no haya terminado. Este método se denomina como tubería sin nominar.

Tuberías nominadas:

Ej: mknod fifo pð%

Genera un archivo de nombre fifo que sincronizará procesos.

$ ls -l > fifo&

$ cat fifo

ls es el proceso productor que envía la información generada al archivo fifo que es una tubería nominada. cat desbloquea el proceso anterior, generando la información, es el proceso consumidor.

Coproceso es la gestión de una tubería bidireccional. Kshell permite la implementación de coprocesos.

SEÑALES:

Una señal es un evento prodeucido por el Kernel o por un proceso de usuario. Su estructura básica de datos es un valor de tipo entero y su funcionalidad está determinada por la comunicación entre procesos. Es semejante al tratamiento de interrupciones en MS-DOS.

Existen varios tipos de señales. UNIX SYSTEM V incorpora 19 señales básicas. A partir de estas los diferentes distribuidores añaden nuevas señales. XENIX y BERKLEY incorporan alrededor de 30 señales.

El archivo SIGNAL.H recoge todos los valores de cada señal. Podemos visualizarlo con KILL -L.

Clasificación de las señales:

SEÑALES RELACIONADAS CON LA TERMINACION DE PROCESOS

15 SIGTER Fuerza la terminación de un proceso. Puede ser ignorada.

9 SIGKILL Establece el fin de un proceso y no puede ser ignorada.

SEÑALES RELACIONADAS CON EXCEPCIONES PRODUCIDAS POR UN PROCESO

8 SIGFPE

4 SIGILL

Terminan el proceso y establecen una copia en disco del proceso como "core".


Por ejemplo, cuando un programa quiere acceder a una dirección de memoria que no le corresponde o cuando se hace un cálculo matemático que requiere coprocesador. Si no hay un coprocesador presente en el sistema obtenemos errores en coma flotante.

SEÑALES RELACIONADAS CON LLAMADAS AL SISTEMA

12 SIGSYS Cuando hay demasiados argumentos en una llamada al sistema.

SEÑALES ASIGNADAS POR EL PROCESO DE UN USUARIO

Son las mismas, pero se envían con KILL -n.

SEÑALES RELACIONADAS CON LA INTERACCION DEL TERMINAL

2 SIGINT Equivale a pulsar ^C.

SEÑALES RELACIONADAS CON LA TRAZA DE INSTRUCCIONES DE UN PROCESO

5 SIGTRAP

SEÑALES ASOCIADAS A LA GESTION DE USUARIO

16 SIGUSR1

17 SIGUSR2

Podrán usarse para diseñar aplicaciones que requieran la sincronización de procesos.

Ordenes de UNIX para enviar y recibir señales:

EMITIR RECIBIR

kill trap (Standard)

kill

Envía una señal con los parámetros disponibles de sincronización.

Formato:

kill -señal pid(s)

Si pid>0 envía la señal al proceso definido.

Si pid=0 envía la señal a todos los procesos, a excepción de los procesos 0 y 1 pertenecientes al mismo grupo que el proceso emisor.

Ej: Se tiene el fichero salir:

echo adios

kill -9 0

Visualiza adios y sale al login. Equivale a usar logout, ^d, exit, ...


Si pid=-1 se envía la señal a todos los procesos, a excepción de los procesos 0 y 1, de los cuales el propietario real es el propietario efectivo del emisor.

Ej:

root El administrador diseña una aplicación

ð

aplicación El propietario real y el propietatio efectivo coinciden. Ambos son el administrador. La aplicación puede ser usada por todos los usuarios del ð sistema.

chmod +s aplicación Activa el bit de usuario efectivo en ejecución.

ð

pepe Pepe ejecuta la ejecución.

Usuario real: Pepe

Usuario efectivo: root

trap

Es un receptor de señales.

Ej:

trap 'echo adios; exit 0' 2

while true

do

echo hola

done

Este es el prototipo de la recepción de señales. Este programa presenta indefinidamente hola hasta pulsar ^C, momento en el cual se activará la captura de señal y se ejecutará 'echo adios; exit 0'

La captura de una señal puede terminar en:

1 ACCION POR DEFECTO

2 IGNORAR LA SEÑAL

3 FUNCION ASOCIADA

ACCION POR DEFECTO

Se establece conforme a los siguientes criterios:

1) Fin de proceso

2) Generación de un archivo de volcado de memoria (core)

3) Ignorar la señal

4) Asociada a la suspensión del proceso. Al recbir una señal un proceso suspende su ejecución y vuelca su contenido a disco en espera de que otra señal reanude su ejecución.

En la versión 4 de UNIX:

SIGSTOP Suspende la ejecución (demora)

SIGCONT Reanuda la ejcución cargando el proceso a memoria.

IGNORAR LA SEÑAL

No hará absolutamente nada al recibir la señal. Señales como la 9 no podrán ser ignoradas.

Ej:


trap ' ' 2

while true

do

echo "Esto es una pena"

done

Aunque enviemos una señal de interrumpir al proceso este no se verá afectado y seguirá visualizando la línea de echo. Si se envía por segunda vez un ^C entonces si será interrumpido, ya que las señales necesitan realimentarse, porque su valor es booleano.

Ej:

trap ' ' 2

while true

do

echo Hola

trap ' ' 2

done

De este modo no se podrá interrumpir con varias pulsaciones de ^C porque la recepción de la señal se está realimentando dentro del bucle. Se asemeja a BREAK=OFF de MS-DOS.

FUNCION ASOCIADA

Función de usuario o guión-shell.

Ej:

adios trap 'ksh adios; exit 0' 2

while true

echo adios do

exit 0 echo hola

done

Ejecuta una orden externa al recibir una señal.

También puede ser un módulo:

Ej:

trap 'adios; exit 0' 2

adios( )

{

echo adios

}

#Programa principal

while true

do

echo hola

done

Ej: Crear un usuario que permita echar abajo el sistema si se interrumpe la ejecución del archivo .profile.

PLANIFICACION DE PROCESOS


SYSTEM V contiene una serie de órdenes para planificar pocesos en el tiempo:

nohup permite que le proceso continúe ejecutándose después de que el usuario se haya desconectado del sistema. Impide que una señal de fin de sesión interrumpa la ejecución de la orden.

Formato:

nohup orden arg(s)&

Ej:

trap ' ' 1

orden fichero&

batch ejecuta tareas cuando la carga de CPU los permita. Es inmune a la señal de fin de sesión.

$ batch ð%

orden(es)ð% $ batch < fichero ð%

^d

at ejecuta procesos determinados por una fecha de ejecución.

$ at hora fecha ð%

orden(es)ð% $ at hora fecha < fichero ð%

^d

Opciones:

-L: presenta la lista de planificación de procesos pendientes

-r: permite borrar trabajos planificados

hora: 0-23, mes. día, año

Ej:

at 0:00 3 Aug 22, 1995 pepe

cron es un proceso demonio que se carga en el proceso init y ejecuta archivos identificados como crontab. Este proceso visualizará y gestionará este tipo de archivos verificando el tipo de órdenes que contienen y, si son adecuadas a la fecha del momento, las ejecutará. Los archivos crontab son ficheros de texto con 6 campos, 6 cadenas separadas por blancos (o el IFS predeterminado).

Campos:

1. Minutos 0-59

2. Horas 0-23

3. Día del mes 1-31

4. Mes del año 1-12

5. Dia de la semana 0-6, siendo 0 Domingo, 1 Lunes, ...

6. Orden a ejecutar

Ej: Archivo crontab:

30 2 1 * * echo ¡Paga el alquiler!


0 1 24 12 * echo Mañana es Navidad.

0 1 * * 1 /usr/pepe/aplicacion

Permite usar * ó , para no indicar el valor de un campo.