La estructura de Unix se amolda a un típico modelo de capas, de forma que cada capa únicamente puede comunicarse con las capas que se hallan en los niveles inmediatamente inferior y superior. El núcleo (kernel) del sistema interactúa directamente con el hardware y proporciona una serie de servicios comunes a los programas de las capas superiores, de forma que las peculiaridades del hardware permanecen ocultas. Como los programas son independientes del hardware, es fácil mover programas entre sistemas Unix que se ejecutan en hardware diferente. KERNEL: es el núcleo del sistema, realiza funciones directamente relacionadas con el hardware. No se relaciona con el usuario. Permanece oculto. Está formada por dos partes importantes: Administración de procesos: asigna y administra los recursos de la computadora, controla la ejecución de los procesos, planifica el tiempo de los procesos que corren a la vez y determina los privilegios de cada uno. Administración de dispositivos: supervisa la transferencia de datos entre la memoria principal y los periféricos (discos, cintas, impresoras, terminales, etc.) La ejecución de un proceso en UNIX se divide en dos niveles: nivel usuario y nivel kernel. Cuando se produce una llamada al sistema se pasa del modo usuario al modo kernel. Éste analiza la llamada, la ejecuta y devuelve el control a modo usuario. Esta diferenciación de modo se produce porque los procesos en modo usuario pueden acceder a sus instrucciones y datos, pero no a instrucciones y datos del kernel o de otros usuarios; mientras que el modo kernel puede acceder a todos los datos e instrucciones del sistema. Hay instrucciones privilegiadas a las que sólo se puede acceder en modo kernel, el cual reside permanentemente en memoria. SHELL: es un utilitario del sistema (no forma parte del kernel). Es el intérprete de comandos. Su tarea es tomar los comandos enviados por el usuario, interpretarlos y llamar a las rutinas correspondientes. Existen distintas versiones del SHELL: sh (standard shell) csh (c-shell) vsh (visual shell) rsh (restricted shell) ksh (korn shell) Cada usuario puede elegir su propio shell. Un shell muestra un indicador (prompt) para indicar al usuario que está preparado para aceptar una orden o instrucción. Para introducir una orden desde el teclado, se escribe el nombre de la orden junto con la información que esta requiera y se pulsa la tecla retorno de carro. Esta línea tecleada se denomina línea de comandos u órdenes. Cuando el shell lee una línea de comandos, extrae la primera palabra, asume que éste es el nombre de un programa ejecutable, lo busca y lo ejecuta. El shell suspende su ejecución hasta que el programa termina, tras lo cual intenta leer la siguiente línea de órdenes. Comandos comunes del sistema de archivos ls listar los nombres de todos los archivos en el directorio actual ls filenames listar solo los archivos nombrados ls –t listar por orden de tiempo, primero el más reciente ls –1 lista larga: más información; también ls –lt ls –u listar por tiempo el último en usarse; también ls –lu, ls –lut ls – r listar en orden inverso; también –rt; -rlt; etc ed filenames editar archivo nombrado copiar file1 en file2, sustituir el file2 anterior si existe mv file1 file2 mover file1 en file2, sustituir el file2 anterior si existe rm filenames suprimir irrevocablemente los archivos nombrados cat filenames imprimir contenidos de los archivos nombrados pr filenames imprimir contenidos con encabezado, 66 lineas por página pr – n filenames imprimir en n columnas pr – m filenames imprimir lado a lado archivos nombrados (columnas múltiples) wc filenames contar renglones, palabras y caracteres en cada archivo wc –1 filenames contar renglones de cada archivo grep pattern filenames imprimir líneas que coincidan con pattern grep –v pattern files imprimir líneas que no coincidan con pattern sort filenames clasificar alfabéticamente los archivos por renglón tail filename imprimir los últimos 10 renglones de archivo tail –n filename imprimir los últimos n renglones del archivo tail +n filename comenzar a imprimir el archivo en el renglón n cmp file1 file2 imprimir localización de la primera diferencia diff file1 file2 imprimir todas las diferencias entre archivos ¿ POR QUE UN SHELL PROGRAMABLE? El shell de Unix no es un caso típico dentro de los intérpretes de comandos: aunque permite al usuario ejecutar comandos en la forma usual, por ser un lenguaje de programación, puede hacer mucho más. Al usar shell el usuario escribe siempre pequeños programas de una línea. El shell trabaja así: se le programa constantemente, pero eso es tan fácil y natural que uno no lo considera como programación. El shell hace algunas cosas como iterar, redireccionar E/S con <y>, y expandir nombres de archivos con *, por lo que ningún programa necesita hacer eso; y algo más importante: la aplicación de estos recursos es uniforme en todos los programas. OTROS UTILITARIOS: compilador “C”, procesador de texto y editores, utilitarios de matemática (bc), utilitarios de comunicación y redes, etc. Conceptos básicos ARCHIVOS Es una estructura de almacenamiento de información. Para Unix todo dispositivo de sistema es un archivo. Se pueden distinguir tres tipos de archivos: comunes (ordinary files): textos, programas fuente, objeto, ejecutables, etc. En este sistema operativo los archivos son sólo una secuencia de bytes (no tiene en cuenta registros, ni índices, ni reconoce marca de eof). La asignación de espacio es dinámica. especiales (special files): dispositivos físicos (terminales, impresoras, cintas, etc) y otros (named pipes por ejemplo). directorios (directory files): son archivos que a su vez contiene referencias de archivos. Los directorios se crean para mantener la información en forma ordenada, agrupan archivos con alguna relación. A un directorio contenido dentro de otro directorio se le denomina subdirectorio y el directorio que lo contiene se llama directorio padre. FILESYSTEM Es el sistema de archivos. En Unix dicho sistema está organizado con estructura de árbol invertido, donde cada nodo es un archivo (ya sea un directorio o un archivo común). Todo filesystem está asociado a un dispositivo físico direccionable (el cual lo contiene). Cada sistema operativo tiene por lo menos un filesystem. Este es el root filesystem, es creado en el momento de instalación. El proceso de inicialización del sistema monta automáticamente el filesystem de root y luego se puede montar más filesystems sobre directorios vacíos. PROCESOS Un proceso es un programa en ejecución. Como sabemos, varios procesos se pueden ejecutar al mismo tiempo pero la CPU sólo puede atender uno a la vez. Mientras un proceso corre, los otros procesos activos esperan. Los procesos son las únicas entidades activas en Unix. Ejecutan un único programa y tienen un único flujo o hebra (thread) de control. Un proceso sólo puede iniciar su ejecución (nacer) si es creado por otro proceso. El proceso más antiguo se denomina padre y el creado, hijo. Un proceso padre puede engendrar varios hijos, pero un hijo únicamente puede tener un padre. Cuando un proceso padre acaba su ejecución (muere), generalmente mueren con él todos sus hijos. Todo proceso tiene una tabla de archivos abiertos por procesos; al crearse un proceso se generan automáticamente tres entradas en dicha tabla: standard input (por default es el teclado). standard output (por default es la pantalla). standard error (por default es la pantalla). USUARIOS No están asociados a un puesto de trabajo. Todo usuario puede estar conectado en el sistema en más de un puesto de trabajo a la vez, cada usuario está asociado a su directorio de trabajo (HOME). Todo archivo tiene un dueño que debe ser el usuario del sistema. Hay distintos tipos de usuarios: superusuario root sysadmin otros comunes especiales sysinfo bin lp Los usuarios pueden ser agrupados de acuerdo a la tarea que desarrollen. El grupo por default es el group. MANIPULACIÓN DE ARCHIVOS En distintos directorios puede existir un archivo con el mismo nombre, sin que el sistema tenga problemas en reconocerlo. Esto se debe a que no sólo tiene en cuenta su nombre local, sino que toma el nombre completo considerando todos los directorios por los que debe pasar desde la raíz “/” hasta llegar a él. Al nombre completo se lo llama “pathname” del archivo ya que indica el camino en el árbol del filesystem hasta llegar al archivo. El formato es el siguiente: /arch1/ arch2 / ......archn/ arch Donde los arch i (1<= i <= n), son archivos directorios y arch puede ser un archivo directorio o un archivo común. La primer “/” indica la raíz del filesystem , y las restantes son sólo separadores de archivos. Debido a esto es que un nombre de archivo no puede contener una “/”. Todo archivo directorio en el filesystem es un nodo no terminal con una referencia a sí mismo llamada „.‟, y una referencia al padre llamada „..‟. Al referenciarse a un archivo en cualquier comando, se lo puede hacer con su pathname completo, o sea indicando el camino en el filesystem desde root “/” o con su pathname relativo, o sea a partir del directorio donde el usuario se encuentra posicionado. Manejo de memoria Dependiendo de la computadora en la que se ejecute, Unix utiliza dos técnicas de manejo de memoria: swapping y memoria virtual. Lo estándar en Unix es un sistema de intercambio de segmentos de un proceso entre memoria principal y memoria secundaria, llamado swapping lo que significa que se debe mover la imagen de un proceso al disco si éste excede la capacidad de la memoria principal, y copiar el proceso completo a memoria secundaria. Es decir, durante su ejecución, los procesos son cambiados de y hacia memoria secundaria conforme se requiera. Si un proceso necesita crecer, pide más memoria al sistema operativo y se le da una nueva sección, lo suficientemente grande para acomodarlo. Entonces, se copia el contenido de la sección usada al área nueva, se libera la sección antigua y se actualizan las tablas de descriptores de procesos. Si no hay suficiente memoria en el momento de la expansión, el proceso se bloquea temporalmente y se le asigna espacio en memoria secundaria. Se copia a disco y, posteriormente, cuando se tiene el espacio adecuado - lo cual sucede normalmente en algunos segundos - se devuelve a memoria principal. Está claro que el proceso que se encarga de los intercambios entre memoria y disco (llamado swapper) debe ser especial y jamás podrá perder su posición privilegiada en la memoria central. El Kernel se encarga de que nadie intente siquiera interrumpir este proceso, del cual dependen todos los demás. Este es el proceso 0. Cuando se decide traer a la memoria principal un proceso en estado de "listo para ejecutar", se le asigna memoria y se copian allí sus segmentos. Entonces, el proceso cargado compite por el procesador con todos los demás procesos cargados. Si no hay suficiente memoria, el proceso de intercambio examina la tabla de procesos para determinar cuál puede ser interrumpido y llevado al disco. Hay una pregunta que surge entonces: ¿cuál de los posibles procesos que están cargados será desactivado y cambiado a memoria secundaria? Los procesos que se eligen primero son aquellos que están esperando operaciones lentas (E/S), o que llevan cierto tiempo sin haberse movido al disco. La idea es tratar de repartir en forma equitativa las oportunidades de ejecución entre todos los procesos, tomando en cuenta sus historias recientes y sus patrones de ejecución. Otra pregunta es ¿cuál de todos los procesos que están en el disco será traído a memoria principal?. La decisión se toma con base en el tiempo de residencia en memoria secundaria. El proceso más antiguo es el que se llama primero, con una pequeña penalización para los grandes. Cuando Unix opera en máquinas más grandes, suele disponer de manejo de memoria de paginación por demanda. En algunos sistemas el tamaño de la página en Unix es de 512 bytes; en otros, de 1024. Para reemplazo se usa un algoritmo que mantiene en memoria las páginas empleadas más recientemente. Un sistema de paginación por demanda ofrece muchas ventajas en cuanto a flexibilidad y agilidad en la atención concurrente de múltiples procesos y proporciona, además, memoria virtual, es decir, la capacidad de trabajar con procesos mayores que el de la memoria central. Estos esquemas son bastante complejos y requieren del apoyo de hardware especializado. Llamadas al sistema Las llamadas al sistema son un conjunto de instrucciones que constituyen una interfaz entre el sistema operativo y los programas de usuario. En Unix, las llamadas al sistema toman la forma de funciones del lenguaje C y tienen un formato común. La llamada devuelve un código de salida que indica si la llamada al sistema ha sido satisfactorio o no. Un valor 0 indica que la llamada se ha llevado a cabo sin error y un valor –1 indica que la llamada ha fallado. Si ha habido un fallo, en una variable global se coloca un código de error. Los códigos de error tendrán un significado determinado dependiendo de la llamada al sistema que los produzcan. Protección Cada archivo tiene un conjunto de permisos asociados con él, los que determinan qué puede hacerse con el archivo y quién puede hacerlo. Lo que hacen es proteger a los archivos del uso que le puedan dar los usuarios. Sin embargo, existe un usuario especial llamado superusuario que es aquel que puede leer o modificar cualquier archivo en el sistema. El usuario root posee privilegios de superusuario y es usado por los administradores del sistema. Para impedir que cualquier persona se conecte con el nombre de un usuario y pueda tener privilegios especiales sobre ciertos archivos, existe una palabra clave de acceso o password. Sólo quien conozca la password de un usuario podrá conectarse como ese usuario. El nombre del usuario es la identificación para iniciar la sesión, pero el sistema reconoce al usuario por medio de un número llamado UID (user id). Por lo tanto, podemos encontrar que diferentes nombres de usuario pueden tener el mismo identificador, haciéndolos indistinguibles para el sistema. Además de un UID, se le asigna un identificador de grupo: es el GID (group id), que lo coloca en cierta clase de usuarios. DUEÑO, GRUPO Y PERMISOS DE UN ARCHIVO Todo archivo tiene un dueño, distintos permisos de acceso para el dueño, para el grupo y para otros usuarios. Los permisos pueden ser de lectura, de escritura o de ejecución. Permisos para archivo común Descripción permiso_de_lectura_(r) Se podrá abrir el archivo y ver el contenido de éste permiso_de_escritura_(w) Se podrá abrir el archivo y modificar el contenido de éste. Este permiso no será necesario para eliminar el archivo, pues lo que se modifica es el directorio. permiso_de_ejecución_(x) Se podrá ejecutar ese archivo. Permisos para directorio Descripción permiso_de_lectura_(r) Se podrá ver el contenido del directorio. Se podrá modificar el contenido del directorio, es permiso_de_escritura_(w) decir, se podrá eliminar o agregar archivos. permiso_de_ejecución_(x) Se podrá posicionar en ese directorio. Procesos STANDARD INPUT, STANDARD OUTPUT, STANDARD ERROR Todo proceso tiene una tabla de archivos abiertos asociada. Al crearse un proceso automáticamente se generan tres entradas en dicha tabla. 0 standard input (entrada standard, por default es el teclado) 1 standard output (salida standard, por default es la pantalla) 2 standard error (salida errónea standard, por default es la pantalla) Unix proporciona un mecanismo sencillo para cambiar la entrada y salida estándar. Este mecanismo se denomina redirección de E/S. También es posible encadenar varios órdenes de forma que la salida estándar de una orden se dirija hacia la entrada estándar de la siguiente. Esta característica se denomina interconexión por tubería (pipeline). Modo de ejecución de los procesos Los comandos que Unix utiliza pueden ser ejecutados en modo: foreground: uno debe esperar a que termine la ejecución del comando para seguir trabajando (primer plano). background: mientras se ejecuta el comando se puede seguir trabajando pues el prompt es devuelto en forma inmediata. El sistema devuelve un número que es el identificador de proceso o PID (process-ID). Comunicación entre procesos Existen varios mecanismos por medio de los cuales los procesos se pueden comunicar. En primer lugar, es posible crear canales unidireccionales para la comunicación entre dos procesos, de forma que uno escribe una secuencia de bytes que es leída por otro. Estos canales se llaman pipes (tuberías). El uso normal de los pipes es la comunicación entre un proceso padre y un proceso hijo, de forma que uno escribe y el otro lee. Los procesos se pueden sincronizar mediante pipes, ya que cuando un proceso intenta leer de un pipe vacío, permanece bloqueado hasta que hay información disponible. Señales Las señales son un mecanismo que se usa para notificar a los procesos la ocurrencia de sucesos asíncronos. Estos sucesos pueden ser por ejemplo una división por cero, la muerte de un proceso hijo, etc. Cuando se produce algún suceso de este tipo, el proceso en cuestión recibe una señal, lo que causa la interrupción de la ejecución del proceso con el fin de que la señal pueda ser tratada. Las señales pueden ser enviadas por otros procesos o por el sistema operativo. Existe un identificador para cada tipo de señal. Esto identificadores varían de una versión de Unix a otra. Los procesos pueden decirle al sistema la acción a tomar cuando reciban una determinada señal. Las opciones son ignorar la señal, aceptar la señal o dejar que sea el sistema el que trate la señal, que es la opción por defecto. Si la elección es aceptar la señal, debe especificar un procedimiento para el tratamiento de la misma. Cuando la señal llega, el flujo de control del proceso cambia a la rutina manejadora de la señal, y cuando ésta termina, devuelve el control al proceso. Entrada / salida Para que los programas puedan acceder a los dispositivos físicos, Unix los integra dentro del sistema de archivos mediante los archivos especiales, de forma que a cada dispositivo se le asigna un archivo que se encuentra, normalmente, en el subdirectorio /dev. Los archivos especiales son accedidos de la misma forma que los ordinarios. Es decir que se los puede abrir, leer y escribir. De esta manera no es necesario ningún mecanismo adicional para realizar la entrada / salida. Otra de las ventajas que posee es que las reglas de protección de archivos se aplican a los dispositivos, lo que permite controlar los accesos. Los archivos especiales se dividen en dos categorías: dispositivos de bloques y dispositivos de caracteres. Los dispositivos de bloques consisten en una secuencia numerada de bloques, de forma que cada bloque puede ser accedido de forma individual. Se usan para discos. Los dispositivos de caracteres se usan normalmente para dispositivos que leen o escriben secuencias de bytes, tales como terminales, impresoras, mouse, etc. Ordenes de UNIX más comunes A continuación se enumeran algunas de las órdenes más empleadas de UNIX. Los formatos de las órdenes se corresponden con la versión de UNIX SunOS. Ordenes para el manejo de directorios pwd Muestra por pantalla el nombre de camino completo del directorio actual cd [directorio] Cambia el directorio de trabajo. Si no especifica ningún parámetro, establece como directorio de trabajo el directorio de conexión (directorio home) del usuario. ls [-aAcCdfFgilLqrRstu1] [fichero(s)] Muestra el contenido de un directorio. Algunas de las opciones más comunes son: · F: Si el fichero es ejecutable o un directorio muestra un asterisco( *) o una barra ( /) detrás del nombre, respectivamente. · R: Listado recursivo. Lista ficheros y subdirectorios. · a: Lista todas las entradas. Normalmente, los ficheros que empiezan por punto ( .) no se muestran. · l: Listado en formato largo. Muestra el modo, número de enlaces, propietario, tamaño en bytes y tiempo de última modificación de cada fichero. mkdir [-p] directorio Crea un directorio. La opción -p permite que los directorios padres que falten sean creados. rmdir directorio Borra un directorio, siempre y cuando esté vacío. Ordenes para el manejo de ficheros cat [-benstuv] [fichero(s)] Lee cada fichero especificado como parámetro y muestra sus contenidos por pantalla. Si no se introduce ningún fichero como parámetro, lee de la entrada estándar. cp [-ip] fichero1 fichero2 cp -rR [-ip] directorio1 directorio2 cp [-iprR] fichero(s) directorio Copia el contenido de fichero1 en fichero2. El segundo modo permite copiar recursivamente directorio1, junto con sus ficheros y subdirectorios, a directorio2. Si éste último no existe, se crea. Si existe, se realiza una copia de directorio1 dentro dedirectorio2 (será un subdirectorio). Con el tercer modo, cada fichero se copia en el directorio indicado. Las opciones r y - R indican comportamiento recursivo. rm [-fir] fichero(s) Borra ficheros y directorios. La opción -r indica comportamiento recursivo y se emplea para borrar directorios. mv [-fi] fichero1 fichero2 mv [-fi] directorio1 directorio2 mv [-fi] fichero(s) directorio Mueve ficheros y directorios dentro del sistema de ficheros. Equivale a renombrar un fichero o directorio. ln [-fs] fichero [enlace] ln [-fs] camino directorio Crea una nombre adicional, llamado enlace, a un fichero. Un fichero puede tener varios enlaces. find lista_de_directorios expresion_de_busqueda Busca ficheros recursivamente a partir de los directorios señalados enlista_de_caminos, buscando aquellos ficheros que safisfacen unaexpresión_de_búsqueda. No se siguen los enlaces simbólicos hacia otros ficheros o directorios. La expresión de búsqueda consta de una o más expresiones primarias, cada una de las cuales describe una propiedad de un fichero, aunque algunas indican una acción a tomar. Las expresiones primarias se pueden combinar mediante los operadores lógicos! (NOT), -a (AND, que se asume por defecto) y –o (OR). file [-f ffich] [-cL] [-m mfile] fichero ... Determina el tipo de un fichero examinando su contenido. du [-s] [-a] fichero ... Muestra el número de bloques de disco usados por un conjunto de ficheros y directorios df [-a] [-i] [-t type] [filesystem ...] [fichero ...] Muestra el espacio libre en el sistema de ficheros Ordenes para el control de procesos ps [-acCegklnrStuvwxU] Muestra el estado de los procesos del sistema. Sin argumentos, muestra información sobre los procesos asociados a la sesión del usuario. kill [-señal] pid ... Envía una señal a un proceso. Por defecto, se envía la señal de terminación del proceso (SIGTERM). Esta señal puede ser ignorada por el proceso, por lo que para eliminar de forma segura un proceso es necesario enviarle la señal de terminación incondicional (señal 9). nice [-numero] orden [argumentos] Permite modificar la prioridad con la que se ejecutará un proceso. La prioridad del proceso se aumentará en la cantidad señalada por numero. A mayor valor de numero, menor prioridad. Por defecto, numero toma el valor de 10. Es posible aumentar la prioridad de un proceso si numero es un valor negativo, pero en esta posibilidad únicamente puede ser usada por el superusuario. Ordenes para seguridad y protección chmod [-fR] modo fichero ... Cambia los permisos (modo) de uno o varios ficheros o directorios. Unicamente puede ser usado por el propietario del fichero (o el superusuario). El modo del fichero se puede especificar de forma absoluta o de forma simbólica. El modo absoluto es un número octal que indica los permisos del fichero (ej.: chmod 444 datos). El modo simbólico es una cadena que tiene la forma [quien] operador permiso [operador permiso] donde quien es una combinación de las letras u (usuario), g (grupo) y o (otros) ó a (que equivale a ugo), operador es + (añade un permiso), - (elimina un permiso) ó =(establece un permiso); y permiso es una combinación de r, w ó x. chown propietario fichero ... Cambia el propietario de un fichero. Sólo puede ser empleada por el propietario del fichero o por el superusuario. En la versión de UNIX SunOS, únicamente puede ser empleada por el superusuario. passwd Permite cambiar la palabra de paso del usuario. Ordenes varias diff Muestra las diferencias, línea por línea, entre dos ficheros grep Busca las líneas de un fichero que contienen una determinada cadena o expresión regular head Muestra las primeras líneas de un fichero tail Muestra las últimas líneas de un fichero wc Cuenta las líneas, palabras y caracteres de un fichero who Muestra los usuarios que se encuentran conectados al sistema whoami Muestra el nombre del usuario de la sesión activa. man Muestra las páginas del manual de referencia.