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