Sobre este curso HTML.
Planteamiento
del curso.
Resumen de los
capítulos.
ÍNDICE
POR TÉRMINOS
I. INTRODUCCIÓN
II. PRIMEROS MOVIMIENTOS EN UNIX (I)
III. PRIMEROS MOVIMIENTOS EN UNIX (II)
El objetivo de un Sistema Operativo (en adelante S.O.) serio es el de crear una máquina virtual para la que sea sencillo trabajar. Es decir, ocultar el hardware (en adelante será referido como "hardware" o "HW" indistintamente). De esta forma, dos arquitecturas distintas con el mismo S.O. parecerán la misma máquina. Por ejemplo, una SUN-10 con SunOS 4.2 (UNIX BSD 4.2 para SUN) y un PC-386 con FreeBSD (UNIX BSD 4.2 para PC) se antojarán iguales al usuario (no en prestaciones, por supuesto). Por el contrario, una misma arquitectura con dos S.O. distintos se presentará como dos máquinas distintas. Por ejemplo, un PC será completamente distinto con MS-DOS 6.2 o con Slackware LINUX 1.2 (UNIX SYSTEM V para PC) como el que se regaló en el número 2 de Sólo Programadores.
Esta ocultación de hardware debe realizarse de un modo cómodo y seguro. Debe ser cómodo para poder utilizar los servicios del mismo sin problemas, aunque no directamente sino a través del S.O., en este caso, el UNIX. Y debe ser seguro para liberar al programador de la preocupación de evitar catástrofes, función de la que se debe encargar el propio sistema. A los programadores de DOS esto de la ocultación puede parecerles una desventaja, sin embargo esto es porque el DOS no realiza esta función, al menos, de forma "comoda y segura".
Desde una visión amplia, el S.O. debe suponer:
Un entorno de mantenimiento y creación de programas
Un interfaz sofisticado de operaciones para el programador, un intérprete de comandos
La correcta gestión de recursos del sistema.
Desde una visión más restringida, se considera el S.O. como el núcleo o kernel del sistema con las funciones y estructuras de datos necesarias para GESTIONAR recursos. Así pues, el S.O. debe:
ejecutar programas
asignar recursos (CPU)
encargarse de la protección del sistema
las operaciones de entrada y salida
la gestión de usuarios y procesos
la detección de errores y
la manipulación del sistema de ficheros.
Llegados a este punto, los programadores con experiencia en DOS advertirán que en la mayoría de los casos son ellos los que se encargan de estas funciones en lugar del propio sistema.
UNIX, como la mayoría de los S.O. actuales es un sistema multiusuario y multitarea. Esto influye en la gestión de la protección del sistema que soluciona de la siguiente forma:
Todas las operaciones de ENTRADA/SALIDA son realizadas por UNIX en el llamado modo supervisor, modo de ejecución en el que el S.O. toma control total del ordenador arrebatándoselo al programa de usuario. El usuario, sin embargo, tiene la impresión de ser él quien realiza la operación invocando una system call o llamada al sistema desde programa. La forma de una system call es la de una función C cualquiera y es la forma que tiene el usuario de interactuar con el sistema.
UNIX tiene un absoluto control de la memoria, gestionando límites de zona para usuarios y para sí mismo y proporcionando llamadas para petición y liberación. Podría compararse con el modo protegido de un extender de DOS.
Al ser un S.O. multiusuario y multitarea pero monoprocesador, debe realizar la gestión de la CPU asignándosela o arrebatándosela a los programas de usuario (sistema de tiempo compartido).
Es importante entender que un S.O. como UNIX "está en
todas partes" y "nada escapa a su control". De este
modo, existe un modo dual de ejecución de programas: modo
usuario en el que el programa de usuario tiene el control y modo
supervisor o monitor en el que es una rutina del propio S.O. la
que controla el ordenador.
La entrada en modo supervisor o
activación del S.O. se producirá por uno entre tres
motivos:
Una llamada al sistema
Una interrupción (hardware o software)
Un trap o interrupción especial hardware que generalmete aniquila el proceso que la provocó
Un S.O. moderno, se desarrolla en general de forma modular, por lo que se estructura jerárquicamente en los siguientes niveles:
Gestión del procesador, que realiza el tratamiento del tiempo compartido entre procesos.
Gestión de memoria, que resuelve problemas de protección relativos a la multiprogramación o concurrencia de programas en la misma máquina, es decir, la existencia de varios programas ejecutándose "a la vez" y accediendo concurrentemente a la memoria.
Gestión de procesos, que resuelve los problemas de creación y destrucción de procesos, comunicación entre los mismos, paro, reanudación, paso a primer plano o planos secundarios, etc.
Gestión de dispositivos, para las operaciones de entrada y salida, así como las asignaciones de dispositivos a procesos y su posterior liberación.
Gestión de la información, que gestiona el espacio de nombres y la protección de los entornos de cada usuario frente a otros usuarios dentro y fuera del sistema.
UNIX, a pesar de su gran éxito y de su profunda evolución, se remonta a comienzos de los años '70. Desde sus or¡genes han transcurrido 25 años, inconcebible en informática, donde algo con 5 años es "histórico" o, incluso, "pre-histórico". Quizá esta sea la mejor prueba de su eficacia y potencia. Sin embargo, no fue desarrollado con las técnicas y metodología actuales, por lo que no goza de una estructuración en niveles tan clara. Intentando encajar las piezas y para ofrecer una visión genérica al lector se podría desglosar la estructura de UNIX según la figura 1.
Lo más importante a entender es que una shell o intérprete de comandos, es sólo una parte más en un S.O. aunque mucha gente identifica ambos conceptos. De hecho, es una de las partes menos importantes del sistema ya que si bien facilita la comunicación del usuario con el sistema, es totalmente sustituible e intercambiable hasta el punto en que la mayoría de los S.O. disponen de varias shells e incluso algunas pueden intercambiarse entre sistemas. Así pues, la shell más famosa del DOS es el COMMAND.COM, aunque algunos la sustituyen por QDOS. UNIX, cuenta con numerosas shells que se analizarán en el momento adecuado, siendo las más famosas la sh y la csh; sin embargo, existen versiones de sh para DOS.
Como se puede apreciar en la figura 1. la estructura de UNIX define dos interfaces, una interfaz HW del núcleo y una interfaz de system calls o API (Application Program Interface) para el usuario. Dos sistemas operativos serán compatibles si ambos presentan la misma API o conjunto de system calls aunque los núcleos o kernels de ambos sistemas sean diferentes. Así, un UNIX tipo SYSTEM V sobre una arquitectura RISC será compatible con un UNIX tipo SYSTEM V como LINUX sobre PC porque ambos presentarán el mismo conjunto de system calls (todo esto, en teoría, claro). De hecho, los núcleos de ambos sistemas serán completamente diferentes: uno gestionará intrucciones RISC y el otro, instrucciones CISC. Lo importante es que un mismo programa (en fuentes), funcionará en máquinas tan dispares porque UNIX les presentará la misma máquina virtual.
La máquina virtual UNIX se basa en el concepto de señal. Una señal es una condición que puede surgir durante la ejecución normal de un programa. Se podría considerar un equivalente software a una interrupción o trap hardware.
Reordenando los conceptos expuestos hasta ahora, se puede encontrar un paralelismo entre la máquina real hardware y la máquina virtual UNIX según la figura 2.
Los orígenes de UNIX se remontan al año 1962 en el que el CTSS y el MIT se encuentran investigando en áreas de tiempo compartido y protección. En 1965, Bell Labs (la división de investigación de AT&T), General Electric y el MIT se encuentran trabajando en un macroproyecto llamado MULTICS, previsto para desarrollar una gran potencia de cálculo y almacenamiento de muchos usuarios. De este proyecto, se obtuvieron interesantes resultados (capacidad de multiproceso, árbol de ficheros, shell); pero, como todo proyecto gigante, su complejidad desbordó al equipo que lo emprendió (seguramente no habían estudiado cibernética o teoría de complejidad) así que en 1969 fue abandonado. El caso, es que una de las mejores "cosas" que salieron de allí fue un tal Ken Thompson, un tanto "mosqueado", eso sí, pero con ideas propias que le llevaron a desarrollar ese mismo año un sistema de ficheros propio. A Thomsom, en realidad, lo que le interesaba era derrotar al imperio Klingom jugando al Star Trek, así que se montó una simulación de la galaxia que quitaba el aliento en un sistema GECOS. Y si no lo quitaba, al menos eso le pareció a una tal Dennis Ritchie, que pasaba por allí y también veía Star Trek. El caso es que Thomson encontró un PDP-7 (otro ordenador más potente) y construyó para él su sistema de ficheros para poder jugar mejor con Ritchie sin que nadie les viera.
Bueno, esta es la leyenda que dice que los origenes de UNIX vienen "de Vulcano". Puede que no fuera así, pero lo cierto es que muchos grandes avances han surgido del desarrollo que grandes hombres han hecho para su disfrute en ratos de "ocio" y este fue uno de ellos. Sea como fuere, en el añoo '71, Ritchie y Kernigham crean y utilizan el lenguaje C en un PDP-11 (algo así como un AT), lenguaje nacido para la programación de sistemas. As¡, dos años después en 1973, Ritchie y Thompson re-escriben su engendro en lenguaje C, pero esta vez desarrollan un sistema multiusuario. UNIX había nacido. El sistema, nacido del trabajo y la ilusión de sólo dos hombres, demostró ser algo tan bueno que ese mismo año Bell Labs contaba con 25 instalaciones funcionando con UNIX.
En 1974 aparece un artículo en las comunicaciones del ACM (Association for Computer Machinery) y se distribuye a las universidades. En 1977 ya son 500 los centros y 125 la universidades que utilizan el sistema. Su expansión es fulgurante ya que se distribuye sin licencias y con fuentes. Entre 1977 y 1982 se combina con un sistema comercial y nace UNIX System III. Ya en 1984 existen 100.000 sistemas UNIX en todo el mundo.
Paralelamente en Berkeley
Entre las universidades a la que llego UNIX, se encontraba la University of California Berkeley. Allí se modificó el sistema incorporando una variante notable: la utilización de memoria virtual paginada. Así en 1978 surge UNIX 3BSD (Berkeley Software Distribution). En 1980 DARPA (Defense Advanced Research Projects Office), verdadero motor de investigación en USA, (sí, sí, la de la famosa DARPA InterNet, que pasó a ARPANet o ARPA Internet y de ahí a sólo internet), subvenciona el desarrollo de 4BSD. Poco después surge 4.1BSD incorporando nuevas utilidades como el clásico editor vi y la shell csh. En 1982 SUN desarrolla para sus arquitecturas el sistema SunOS basado en la versión BSD. Un año después surge la versión 4.2BSD que incorpora DEC en VAX y adopta SUN Microsystems. 1984 marca un nuevo hito en la historia de UNIX ya que SUN desarrolla los conceptos de RPC (Remote Procedure Call) y NFS (Network File System) y los incorpora a SunOS.
Panorama actual: familias de UNIX
Cada fabricante ha ido desarrollando sus estándares: AT&T SVID, el interfaz SYSTEM V; HP, UP-UX (tipo SYSTEM V); DEC, ULTRIX (tipo 4.2BSD); Microsoft, XENIX; e IBM, AIX. Como se puede ver, en líneas generales, existen dos tipos de UNIX: tipo BSD y tipo SYSTEM V. También existen implementaciones de tipo académico, como MINIX, desarrollada por Tanembaum con afán didáctico en 1983; o XINU, desarrollada por Comer en 1984. La razón de los distintos nombres que recibe el sistema es que UNIX es una marca registrada de AT&T. Así, cada implementación recibe el suyo propio.
En la actualidad Berkeley acaba de anunciar la salida de 4.4BSD y su retirada del mundo UNIX, por lo que el futuro es de SYSTEM V. SUN, por ejemplo, ha pasado ya a este sistema en la última versión de su S.O. Solaris. Sin embargo, en los últimos años se ha buscado la convergencia de los sistemas. As¡, desde el punto de vista de programación, BSD ha ganado la batalla ya que su interfaz de sockets a pasado a ser el medio clásico de comunicación entre procesos. En su momento, los usaremos.
Se pueden encontrar muchos otros UNIX: SCO, NetBSD, FreeBSD, LINUX, GNU (...) y cada vez más para el mundo PC. En este momento nos detendremos para dirigir una breve mirada a LINUX.
Llegados a este punto habría que despejar cierta confusión sobre LINUX. LINUX es una implementación para PC con interfaz SYSTEM V de libre distruibución. El mantenimiento, traducción de programas y nuevos desarrollos suele realizarse también por personas sin ánimo de lucro. Esta es la razón de que exista no una, sino infinidad de distribuciones de LINUX. En ocasiones, una compañía realiza una distribución, le da un valor añadido y realiza un cobro de manera lícita por este valor añadido y a cambio de soporte y mantenimiento. Entre las distribuciones más famosas podemos encontrar la de Slackware, la de Yggdrassil o la española Omega, en castellano. Por ello, cada distribución cuenta con un proceso de instalación distinto, no se puede hablar de "la instalación de LINUX", sino de "la instalación de ésta distribución de LINUX". Unas se instalan y optimizan solas, algunas apenas hacen nada, otras ofrecen varias instalaciones a elegir. Un usuario experto en administración preferirá basarse en una instalación tipo pero realizará la mayor parte de la configuración él mismo. Cada distribución cuenta con un software distinto y hasta soportan sistemas de ficheros distintos. Así, por ejemplo, Slackware 2.0 es la primera distribución en incluir Linux DOOM. Yggdrassil soporta NFS pero Slackware 1.2, no. Omega está completamente en castellano y da soporte BBS en España, etc. Mañana, cuando el lector sepa un poco más del sistema, podríamos realizar su propia distribución.
A través del curso se irá profundizando en cada uno de los aspectos del sistema, pero a modo de perfil se pueden presentar las siguientes ideas que ser explicadas con detalle en su momento y por ahora definirán mejor el sistema a los lectores más experimentados:
Un sistema de ficheros jerárquico en el que todo se encuentra anclado en la raíz. La mayoría de la literatura sobre el tema dice que el sistema de ficheros UNIX es un grafo acíclico, sin embargo, la realidad es que se trata de un grafo cíclico. El DOS, por ejemplo, es un árbol, con un directorio raíz del que cuelgan subdirectorios que a su vez son raíces de otros subárboles. Un grafo cíclico es como un árbol en el que se pueden enlazar nodos de niveles inferiores con un nivel superior. Es decir, se puede entrar en un subdirectorio y aparecer más cerca de la raíz de lo que se estaba.
El sistema de ficheros está basado en la idea de volúmenes, que se pueden montar y desmontar para lo que se les asigna un nodo del árbol como punto de anclaje. Un sistema físico puede dividirse en uno o más volúmenes.
UNIX realiza un riguroso control de acceso a ficheros. Cada uno se encuentra protegido por una secuencia de bits. Sólo se permite el acceso global al root o superusuario. Por tanto, el universo de usuarios de UNIX se encuentra dividido en dos grupos principales, no sólo para el acceso a ficheros sino para todas las actividades: el root, todopoderoso, para el que no hay barreras; y el resto de los usuarios, controlados por el S.O. según las directivas del root.
Una de las grandes ideas de UNIX es la unificación y compatibilidad de todos los procesos de entrada y salida. Para UNIX, el universo es un sistema de ficheros. De esta forma existe compatibilidad entre ficheros, dispositivos, procesos, pipes y sockets.
El núcleo de UNIX es relativamente compacto en comparación con otros sistemas de tiempo compartido. Introduce la idea de reducir el tamaño del kernel y ceder ciertas funciones a programas externos al núcleo llamados demonios. Esto ha sido muy desarrollado y en la actualidad, la tendencia es el desarrollo de micro-kernels, sin embargo UNIX, aunque pionero, es anterior a estos desarrollos.
El sistema presenta comandos de usuario (es decir, a nivel de shell) para iniciar y manipular procesos concurrentes asíncronos. Un usuario puede ejecutar varios procesos, intercambiarlos e interconectarlos a través de pipes o tuberías, simbolizados por el carácter ¦ (ASCII 124). En DOS, también existe la idea del pipe, sin embargo, al no existir concurrencia de procesos, no se trata de una comunicación en "tiempo real", sino de un paso de información a través de ficheros temporales.
UNIX es un S.O. de red, algo que muchos confunden con un S.O. distribuido, lo que se discutirá en los capítulos de internetworking. Por ello, se ha incluído en su núcleo la arquitectura de protocolos de internet, TCP/IP.
Sintetizando lo expuesto, definiremos a UNIX como un sistema multiusuario y de tiempo compartido.
El usuario introduce comandos y recibe resultados en un terminal.
Todo usuario dispone de un directorio privado llamado home directory sobre el que, exceptuando al root, sólo él tiene control.
La seguridad en UNIX no es una directiva principal debido a su origen y propósito inicial, por lo que se puede recorrer todo el árbol de ficheros (es decir, el grafo), y las protecciones deben ser explícitas y específicas.
El sistema proporciona, también a nivel de shell, importantes facilidades para las comunicaciones entre usuarios y máquinas dentro y fuera del propio sistema.
Y como característica más importante, permite un alto grado de customización o de particularización del entorno según las preferencias de cada usuario a través de ficheros de configuración particulares.
Como contrapartida o desventaja hay que advertir que presenta un entorno de órdenes rígido. Al acostumbrarse se presenta realmente eficiente, pero hay que recalcar que será "al acostumbrarse".
Para UNIX el universo es un sistema de ficheros. No existen periféricos, sólo ficheros. De este modo se unifican todos los procesos E/S. Los directorios son ficheros que contienen enlaces con otros ficheros. Terminales, discos compactos e impresoras son ficheros, en teoría se puede escribir y leer de todos ellos. Para encontrar los ficheros en el disco, el sistema utiliza punteros llamados i-nodos. Al borrar un fichero, simplemente se borra su i-nodo; pero, al contrario que en DOS, una vez se ha borrado algo en UNIX es IRRECUPERABLE ya que no hay forma de encontrar de nuevo el camino a la información en disco.
Cada proceso o programa en memoria tiene un owner o propietario que es el sujeto que lo ha lanzado. Desde su nacimiento adquiere los permisos del owner. Cuando un proceso queda huérfano se le denomina demonio o daemon (veremos otras dos acepciones para este término, ésta es la menos usada y precisa).
El sistema no es S.O. de tiempo real. ¡CUIDADO AL DESCONECTAR UN SISTEMA UNIX!, podrían perderse datos que figuran como archivados. El S.O. ejecuta las órdenes cuando quiere y aunque dé por recibida una orden de escritura en disco puede estar dando prioridad a otro programa (realmente realiza una labor de caché interna). Para asegurarse de que todo se refleja en la memoria de masa, es decir, de que se ha escrito de verdad lo que se tenía que escribir, existe la orden sync. Si se desea apagar un ordenador bajo UNIX, se deber entrar al sistema como root o superusuario y ejecutar la orden halt. Una vez el sistema haya realizado las operaciones oportunas, lo notificará y se podrá apagar la máquina sin peligro.
UNIX diferencia las mayúsculas de las minúsculas (case sensitive).
Un sistema UNIX en modo multiusuario (puede arrancarse en modo monousuario para labores de administración) espera la entrada de un usuario al sistema, proceso que recibe el nombre de login. Para ello, el ordenador muestra un mensaje identificándose y la palabra
login:
Para entrar hay que disponer de una cuenta, que es como se llama al hecho de ser reconocido por el sistema y, por tanto, tener acceso. En caso de ser un sistema recien instalado, no habrá aún creada ninguna cuenta excepto la de root, por lo que habra que contestar tecleando "root". En otro caso, se teclea el login o identificativo correspondiente. Tras ello y para comprobar la identidad del usuario, el sistema preguntará
passwd:
esperando un password o palabra clave asociados al login y, si todo va bien, ya se está dentro. Mientras se teclea la palabra clave, no aparece eco en pantalla para que nadie en los alrededores pueda leerla. Por ello, si se produce un error al teclear, el habrá otra oportunidad. En caso de que no haya definida ninguna palabra de paso, obviamente, no se preguntará por ella. Esto suele ocurrir con el usuario root cuando UNIX está recién instalado. Si una vez dentro se desea salir, bastar teclear exit, logout o simplemente CONTROL+D, según el sistema en que uno se encuentre.
Nada más terminar el proceso de login, una shell arranca automáticamente y advierte de su disposición a recibir comandos mostrando un prompt, que por defecto será uno de los símbolos #, %, > ó $, en función de que shell se use y de si uno es el root o no. Este prompt equivale al famoso C:> del DOS y, como este último, es redefinible.
Ya desde dentro se puede empezar a jugar con algunos comandos:
Y Thomson y Ritche dijeron: "No es bueno que el usuario esté sólo" y el manual se hizó. Y así, "gracias a dios", cuando las cosas se ponen difíciles, siempre se puede acceder a los completos manuales de referencia del usuario y del programador directamente desde línea de comando: para ello se dispone de la instrucción man.
Como se introdujo en el primer capítulo del curso, el sistema de directorios de UNIX tiene una estructura arbórea, aunque no se trata de un árbol, como se verá en el apartado dedicado al sistema de ficheros. En este "árbol", cada usuario dispone de un Home Directory, un directorio con su nombre y bajo el cual, puede hacer lo que quiera. Es la parte "física" de la idea de tener una cuenta. As¡ pues, aunque el sistema es multiusuario, cada usuario dispone de una parte privada de disco. Cabe recordar que los ficheros cuyo nombre comienza por punto (.) permanecen ocultos. Para moverse por esta estructura de directorios, se pueden destacar los comandos:
No todo el "árbol" de directorios está compuesto por directorios de usuario. Existen muchos de ellos que son de uso general o del propio sistema y con los que habrá que familiarizarse. Los más importantes son:
Para este primer chapuzón por el mundo UNIX, viene bien conocer algunos otros comandos útiles. Los que se presentan a continuación son de conocimiento obligado para todo usuario:
Ya al final de la sesión de hoy, hay que recordar que no se debe apagar el sistema por las buenas. Si se desea salir del mismo sin que éste deje de funcionar, bastar con teclear exit, logout o CONTROL+D, como se indicaba en la introducción. Si además se desea "tirar" el sistema UNIX, conviene pararlo mediante la instrucción
halt
y esperar a que termine (para ello, se recurda que hay que ser root). Para tirar el sistema se podrá teclear:
shutdown [-r] now
(si pregunta algo, pulsar ENTER)
(apagar)
shutdown se encarga de hacer el halt. La opción -r además rearranca la máquina.
En UNIX la forma de realizar redirecciones es fuertemente dependiente de la shell utilizada; sin embargo, para estos primeros pasos se pueden destacar las características comunes a todas ellas que son, a la vez, las más utilizadas. En principio, se podría señalar que cada proceso UNIX tiene asociadas 3 vías de entrada/salida (E/S) estándares:
Una salida estándar (STDOUT) que por defecto se encuentra conectada al terminal (pantalla) asociado al proceso
Una entrada estándar (STDIN), que por defecto se encuentra asociada al mismo terminal (en este caso, al teclado)
Una salida de error (STDERR), que por defecto se encuentra conectada con la STDOUT
Estos puntos E/S pueden ser redirigidos de una manera en apariencia similar al DOS: así escribiendo
> nombre_fichero
tras el nombre de un comando, que producirá la redirección de su salida a un fichero. De manera análoga se actuará con la entrada escribiendo
< nombre_fichero
También es posible realizar redirecciones de la salida de error, que se estudiarán en el tema dedicado a shells.
El listado 1 ha sido generado mediante la instrucción:
ls -lF /etc > lsetc.txt
Este ejemplo ilustra también la opción -F del comando ls, que hará que aparezca:
un carácter / junto al nombre de los directorios
un * junto al nombre de los ejecutables
un @ junto a los enlaces simbólicos.
El comando ls en linux, además mostrará de distinto color cada tipo de fichero, según se indique en el /etc/DIR_COLORS.
En el capítulo anterior se veía como el comando cat podía mostrar el contenido de un fichero:
cat fichero
Del mismo modo, se podría haber redirigido la salida para copiar el fichero:
cat fichero1 > fichero2
Otro ejemplo de utilización sería no indicar el parámetro de entrada, con lo que el comando leería de la STDIN (teclado). Esto es algo que se puede realizar con un tipo especial de comandos UNIX llamados filtros que se estudiará más adelante. Así, por ejemplo:
cat > notas
copiaría todo lo que se tecleara al fichero notas (para indicar al comando que se ha finalizado habría que teclear CTRL + D). Equivaldría a un copy con: notas en DOS.
Una forma muy potente de comunicación entre procesos es el llamado pipe. Como se señalaba en el capítulo de introducción, un usuario puede ejecutar varios procesos e interconectarlos a través de pipes o tuberías, simbolizados por el carácter ¦ (ASCII 124). A través de un pipe, se realiza una llamada al sistema que interconecta la STDOUT de un comando con la STDIN del siguiente. Ambos procesos se ejecutarán concurrentemente, es decir, en paralelo. No hay que confundir un pipe UNIX con el mecanismo del DOS que utiliza el mismo símbolo, donde no existe concurrencia de procesos sino paso de información a través de ficheros temporales.
Como ejemplo útil, se podría teclear
ls ¦ sort ¦ more
que produciría una salida en pantalla y paginada del contenido del directorio actual ordenado alfabéticamente.
En estos primeros pasos, se supondrá(n) instalada(s) la(s) impresora(s) y se comentará su manejo a nivel de usuario. Desde esta perspectiva el manejo de impresoras se realizará a través de los siguientes comandos:
Para usuarios deseosos de profundizar más en este momento se recomienda la consulta del manual en línea de estos comandos así como de las páginas lpd, lpc y printcap (una buena práctica sería buscar también con man -k printer).
Al ser UNIX un sistema multiusuario suge el problema de la protección y privacidad de la información. Así cada fichero posee un código de 9 bits para regular su acceso. El esquema empleado, clásico en muchos sistemas operativos consiste en dividir el universo de usuarios que ve cada fichero en tres clases:
la clase u (user), formada únicamente por el dueño del fichero
la clase g (group), formada por todos los usuarios que pertenecen al mismo grupo del dueño
la clase o, formada por el resto del universo
(o como diría Gonzalo León, "el universo se divide en yo, mis amigos y mis enemigos").
Un usuario puede pertenecer a más de un grupo pero un fichero sólo puede pertenecer a uno. De esta forma, parte de los ficheros de un usuario podrían ser accedidos por uno de los grupos a los que el usuario pertenece y parte por otro grupo. Para entender mejor las relaciones de inclusión entre grupos, consúltese la figura 1.
Como siempre es el root el que decide qué usuarios pertenecen a qué grupos, los cuales se suelen organizar atendiendo a razones de trabajo. La lógica de esto es que un usuario concreto (clase u), puede tener en un fichero una carta de su novia, que no le interesa que lea nadie más. Sin embargo, también dispondrá de una serie de ficheros a los que tendrá que permitir el acceso a su grupo de trabajo (clase g) pero no querrá que los vea nadie más. Del mismo modo, podría también interesarle que todo el mundo (clase o) pudiera acceder a la información contenida en otra serie de ficheros. El root, como superusuario, es caso aparte, ya que dispone de acceso a todos los ficheros del sistema.
Existen 3 formas de acceder a un fichero: lectura, escritura y ejecución. Así, los 9 bits de protección de acceso de cada fichero se encuentran divididos en 3 grupos de 3 bits. Cada grupo de 3 bits indica acceso a u, g, o, respectivamente y cada bit de cada grupo indica:
bit 1 (r), permiso de lectura
bit 2 (w), permiso de escritura
bit 3 (x), permiso de ejecución.
No hay mejor forma de entender el proceso que acceder a las cadenas de bits de protección de cada fichero, primero para su lectura y más tarde para su modificación. Para ello, se empleará la opción -l del comando ls que proporciona una salida como:
--rwxr-xr-x 1 echeva 127 Jan 20 1:24 fichero
La salida aquí presentada se obtendría de un UNIX "estándar". En Linux, se obtendrá la presentada en el listado 1.
Observando la figura 2 se entenderá mejor el significado de los bits de la cadena.
Cuando un bit este activo, se mostrará la letra correspondiente a la forma de acceso que representa y si está inactivo aparecerá como un guión. Así, el ejemplo presenta un fichero con permisos de lectura, escritura y ejecución (rwx) para el propietario, y de sólo lectura y ejecución (r-x) para todos los demás. En algunos casos puede aparecer una s en el lugar de un bit de permiso, que indicará un setuid o setgid, es decir, herencia de propiedades de grupo o de propietario para el usuario que ejecute el fichero. En el capítulo anterior se mencionaba que un proceso adquiría los permisos del sujeto que lo hab¡a lanzado. Sin embargo, en ocasiones, puede interesar que se hereden los permisos del propietario del fichero. Es el caso del comando passwd, proceso que debe poder ejecutar cualquiera y en cambio, tener permisos de root para modificar el fichero /etc/passwd que sólo tiene permiso de escritura para el mismo root. Examinando sus cadenas de permiso (listado 1) se puede ver cómo dispone de factor de herencia. Se puede también observar que existe un décimo carácter que definirá el tipo de fichero:
s, si es un socket
l, si es un enlace simbólico
d, si es un directorio
c, si es un dispositivo de caracteres
b, si es undispositivo de bloque
-, si es un fichero corriente
(se recuerda que para UNIX todo son ficheros).
Para saber a qué grupo pertenece cada fichero se puede utilizar
ls -lg
En Linux la opción -g carece de significado, ya que queda englobada directamente en la opción -l. En general, existe un grupo principal al que pertenece cada usuario cuyo número se encuentra en su entrada en el fichero /etc/passwd. Es a este grupo al que pertenecerán por defecto todos los ficheros de ese usuario.
Para alterar los permisos de un fichero, UNIX provee la intrucción chmod. Este comando reconoce dos tipos de sintaxis: una basada en cadenas mnemónicas expresando modificaciones (más intuitiva) y otra basada en combinaciones en base octal (más potente).
La sintaxis para el primer caso es:
chmod quién op permiso [[op2 permiso2]...] fichero
dónde
quién expresa el conjunto de usuarios a los que va a afectar el cambio de permisos y puede ser:
una combinación cualquiera de u, g, o
o la letra a o ninguna letra para designar a todos
op representa la operación a realizar y puede ser
+ para añadir
- para quitar o
= para "resetear" el permiso.
permiso, obviamente, representa el permiso que se desea modificar.
Así, por ejemplo:
chmod g -r fichero
quitará permiso
de lectura para la clase g (grupo) y dejar el resto de los
permisos inalterados
chmod +x fichero
hará ejecutable
un fichero para todo el universo y
chmod ug +x fichero
lo hará sólo
para el usuario y su grupo.
La segunda sintaxis del comando, aunque más compleja, permite cambiar de un sola y breve vez todos los permisos de un fichero: si se trata por separado cada uno de los grupos de usuario, se encontrará 3 bits de permiso para cada uno. Con 3 bits podrán expresarse hasta 8 combinaciones, desde 000 hasta 111. Así, se puede expresar por un dígito octal los permisos de cada grupo.
Por poner un ejemplo:
Supongamos que se desea que todo
el universo pueda leer un fichero pero sólo el propietario
pueda modificarlo. La estructura de permisos será:
u (rw), g(r), o(r)
Es decir
rw- r-- r--
o lo que es lo mismo
110 100 100
que en octal será
644
Por tanto, habrá que teclear:
chmod 644 fichero
Existen dos comandos análogos con los que se puede identificar a otros usuarios conectados a la vez en la misma máquina: who y w cuyas salidas pueden verse en el listado 3. Esta información es actualizada dinámicamente por el sistema y se encuentra en el fichero /etc/utmp. Como puede apreciarse, la informaci¢n de w es más completa y presenta los siguientes campos:
user, con los login o nombres de usuario, que aparecerán repetidos si el usuario tiene abierta más de una sesión (por ejemplo, en linux, pulsando ALT junto con las teclas de función se puede saltar de una sesión a otra a través de terminales virtuales)
tty, que muestra el terminal a que se encuentra asociada la sesión
login, que indica la hora de inicio de la misma
idle, que muestra el tiempo en minutos que ha transcurrido desde que el usuario pulsó por última vez una tecla
JCPU o tiempo de CPU utilizado por todos los procesos controlados por el terminal;
PCPU o tiempo de CPU usado por el proceso activo y
what o proceso activo de la sesión
Para obetener información sobre un usuario se encuentre éste o no conectado en ese momento a la máquina, se dispone del comando
finger [name]
que presenta informacion sobre todos los usuarios de login name o con la cadena name en su nombre real. En caso de teclearse sin argumentos, dará una información similar a who de todos los usuarios conectados a la máquina. La salida de este comando suele presentar un campo Project, que muestra la primera línea del fichero .project (en caso de que exista) del home directory del usuario por el quese pregunta y un campo Plan que muestra el fichero .plan completo