Ingeniero en Informática
Unix
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
- 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.
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.
Descargar
Enviado por: | El remitente no desea revelar su nombre |
Idioma: | castellano |
País: | España |