BLOQUE III. UNIX A NIVEL DE USUARIO
1. Tipos de usuario
UNIX proporciona un entorno particularmente bueno para grupos de personas (usuarios) que trabajen conjuntamente en el mismo proyecto o proyectos relacionados. Todo usuario en UNIX pertenece a un grupo. El grupo tendrá asignado un nombre de grupo e identificador de grupo.
Básicamente, hay dos tipos de cuentas de usuarios:
Hay algunas operaciones del sistema que sólo el superusuario puede realizar. Fijar la fecha del sistema, montar un sistema de ficheros, crear nuevos usuarios y declarar ficheros especiales son algunos ejemplos de ellas.
Hay varias maneras de llegar a ser superusuario. La primera de ellas es llevar el sistema al estado monousuario. Esta situación ocurre cuando se arranca el sistema. En el momento de la carga inicial, el shell inicial se ejecuta con todos los privilegios del superusuario. En un sistema multiusuario se puede salir de sesión para entrar de nuevo como superusuario, o se puede obtener la categoría de superusuario por medio de un comando. Se identifica porque aparece en pantalla un prompt especial (el carácter #).
2.1 Acceso al sistema:
Para incrementar la seguridad, cada usuario puede añadir opcionalmente una contraseña de acceso al sistema. La existencia de contraseña puede ser impuesta por el administrador.
Cuando se va a trabajar desde un terminal conectado directamente al ordenador, nada más encenderlo aparecerá un mensaje solicitando la identificación del usuario. Este mensaje puede ser modificado por el administrador. En este momento el usuario puede introducir el identificativo que se le haya asignado y pulsar retorno de carro. Es importante que el identificativo sea introducido en minúsculas, pues en caso contrario el sistema asume que el terminal sólo dispone de mayúsculas y mantendrá la comunicación de esta forma durante toda la sesión de trabajo. Esto puede traer complicaciones, pues el sistema UNIX diferencia mayúsculas de minúsculas.
En caso de que el usuario tuviera contraseña de acceso al sistema, le será solicitada a continuación por medio de la palabra "passwd". Para mayor seguridad, la contraseña tecleada por el usuario no aparece jamás en la pantalla. Cualquier equivocación al teclear el identificativo hará que el sistema solicite una contraseña y una vez tecleada ésta, contestará con "login incorrect" y volverá a pedir el identificativo. Con esto se complica el intento de acceso al sistema por usuarios no autorizados, pues no pueden distinguir si el error lo han cometido al introducir el identificativo o la contraseña.
Tan sólo cuando el identificativo de usuario y la contraseña de acceso se han introducido correctamente, aparecerán en pantalla una serie de mensajes (mensaje del día, etc.) y el sistema queda preparado para recibir órdenes del usuario.
Siempre que el sistema esté en espera para recibir órdenes, aparecerá en la pantalla un mensaje indicativo o prompt. Hay más de un tipo de prompt, dependiendo del SHELL:
- Bourne $ - Berkeley % - Creados por el usuario - Super usuario #
Para finalizar la sesión de trabajo basta mantener pulsada
la tecla "Control" y pulsar la d. Otra forma de finalizar la sesión es tecleando exit seguido de
retorno de carro. Una vez finalizada la sesión, el sistema vuelve a mostrar los mensajes con los
que solicita el identificativo de usuario. En este momento se puede apagar el terminal.
2.2 Mensajes previos a la aparición del prompt del shell:
Mensaje del día | Localizado en el archivo /etc/motd. Aparece cada vez que el usuario se identifica ante el sistema. Se crea o modifica con un editor, y es propiedad del administrador. |
news: items... | Indica que existen todos estos nuevos items, que pueden ser accedidos y que todavía no la han sido. Son también propiedad del administrador, y los utiliza para transmitir a los usuarios información no tan crítica como la usada en el mensaje del día. |
you have mail | Indica que el usuario ha recibido nuevos mensajes en su buzón de correo, desde la última vez que accedió a él. |
Para mayor comodidad, e incluso por motivos de seguridad, cuando el administrador registra un usuario también le asigna un directorio de trabajo.
Cuando un usuario se identifica ante el sistema, éste, automáticamente, le sitúa en el directorio asignado, que habitualmente contendrá los archivos y subdirectorios de mayor utilización de ese usuario, sin perjuicio de que pueda cambiarse a otro directorio o utilizar otros archivos de la estructura (siempre que lo permitan los permisos de acceso).
Al directorio en que sitúa el sistema a un usuario cuando se identifica, se le denomina directorio HOME de ese usuario.
3.1 Introducción:
Una vez entrado el nombre de usuario, el mismo programa invoca al programa login con el nombre de usuario como argumento. Este programa se ocupa de comprobar el logname y la contraseña. Si todo está correcto, llama al programa sh que se encarga a su vez de ejecutar los comandos que se encuentran en el fichero .profile en el directorio HOME de cada usuario. Finalmente genera en pantalla el prompt. A partir de aquí, se queda esperando que se introduzcan comandos. El programa sh es el shell.
Cada vez que se introduce un comando, el shell analiza la línea, verifica la sintaxis y lo ejecuta. El ciclo se repite hasta que el usuario se desconecta. Entonces, el programa sh termina su ejecución e init recobra el control iniciando una nueva ejecución de getty para el terminal.
El shell es, por tanto, un procesador de comandos. Pero también ejerce otras responsabilidades: Es el encargado de la redirección de entradas y salidas, es también un lenguaje de programación interpretado, es el encargado de proveer los comandos y variables para controlar y modificar el entorno de usuario (es decir, tiene la función de ser interface de usuario).
Existe en UNIX un conjunto de variables denominadas variables de entorno. Dichas variables son creadas habitualmente por el propio shell en concordancia con el modo y las características dadas por el administrador del sistema al dar de alta al usuario. Estas variables son las que definen el propio entorno de trabajo y son redefinibles por el usuario, lo que agrega flexibilidad al sistema y permite adaptar el entorno al gusto o necesidad de cada uno.
Aparte de estas variables, el shell en UNIX permite agrupar comandos en un programa, dando como beneficio para el usuario un ahorro considerable de tiempo y atención. Para crear este tipo de utilidades en UNIX, disponemos del lenguaje de programación del propio shell. Este lenguaje es un lenguaje interpretado (cada línea del programa es leída y a continuación ejecutada).
El lenguaje de programación shell es mucho más de lo que se necesita para hacer utilidades de tipo batch. Es un lenguaje completo, de alto nivel, que incluye las estructuras fundamentales de la programación. Maneja variables, dispone de instrucciones que controlan procesos iterativos tales como for, while, until; permite parámetros de sustitución y una serie de instrucciones como entrada de datos (read), ejecuciones condicionales (if, case), etc., adecuadas para desarrollar utilidades muy sofisticadas. Sobre todo, este lenguaje permite la posibilidad de emplear todos los comandos del sistema dentro de los propios programas.
El shell permite tres tipos de comandos. Primero, un comando puede ser un archivo ejecutable que contiene el código objeto producido por la compilación de un código fuente (un programa en C por ejemplo). Segundo, un comando puede ser un archivo ejecutable que contiene una secuencia de líneas de comando del shell (shellscript). Finalmente, un comando puede ser un comando interno del shell (en lugar de un archivo ejecutable). Los comandos internos hacen del shell un lenguaje de programación junto con el intérprete de comandos e incluyendo comandos para bucles, comandos para ejecuciones condicionales, un comando para cambiar el directorio actual de un proceso, y muchos más. La sintaxis del shell permite emparejamiento de modelos y procesamiento de parámetros. Los usuarios ejecutan comandos sin tener conocimiento de sus tipos.
El shell busca los comandos en una secuencia de directorios dada, cambiable a petición del usuario por medio del shell. El shell normalmente ejecuta un comando síncronamente, esperando a que el comando termine antes de leer la siguiente línea de comando. Sin embargo, también se permite la ejecución asíncrona, donde se lee la siguiente línea de comando y se ejecuta sin esperar a que el anterior comando termine. Los comandos ejecutados asíncronamente se dicen que se ejecutan en background. Para indicar que un comando se ejecute en background se incluye el carácter & al final de la línea de comando, como por ejemplo "who &" ejecuta el comando who en background.
Como el shell es un programa de usuario y no forma parte del kernel, es fácil de modificar. Por ejemplo, los usuarios pueden usar el C shell para obtener un mecanismo histórico y poder repetir comandos usados recientemente, en lugar del Bourne shell proporcionado como parte del estándar System V. El sistema puede ejecutar varios shells simultáneamente. Los usuarios tienen la capacidad de ejecutar varios procesos simultáneamente, y los procesos pueden crear otros procesos dinámicamente y sincronizar sus ejecuciones, si se desea. Estas características proporcionan a los usuarios un poderoso entorno de ejecución.
La primera palabra es el comando, las restantes palabras son argumentos del comando. Los espacios son usados como separadores entre argumentos. Si por alguna razón fuera necesario incluir un espacio en algún argumento, entonces todo el argumento deberá ser encerrado entre comillas dobles ("), o bien entre comillas simples (').
Los programas en UNIX no tienen conocimiento del formato interno en el que el kernel almacena los datos, tratando los datos como un flujo de bytes. Los programas deben interpretar el flujo de datos como ellos deseen, pero la interpretación no interviene en como el sistema operativo almacena los datos. De esta forma, la sintaxis del acceso a los datos en un archivo está definido por el sistema y es idéntico para todos los programas, sin embargo la semántica de los datos está impuesta por el programa.
Los directorios son iguales a los archivos regulares en este sentido; el sistema trata los datos en un directorio como un flujo de bytes, pero los datos contienen los nombres de los archivos en el directorio en un formato predefinido tal que el sistema operativo y los programas puedan descubrir los archivos de un directorio.
Para el usuario, el sistema UNIX trata a los dispositivos como si fuesen archivos. Los dispositivos, identificados por archivos de dispositivos, ocupan posiciones en la estructura de directorios del sistema de archivos como nodos. Los programas acceden a los dispositivos con la misma sintaxis que se usa cuando acceden a archivos regulares; la semántica de la lectura y escritura de los dispositivos es la misma que la de la lectura y escritura de archivos regulares. Los dispositivos están protegidos de la misma forma que los archivos regulares están protegidos: por su propio conjunto de permisos de acceso. Como los nombre de los dispositivos aparecen iguales que los nombres de los archivos regulares y las mismas operaciones trabajan para dispositivos y archivos regulares, muchos programas no tienen conocimiento internamente del tipo de archivo con el que está trabajando.
lslista todos los archivos del directorio actual en la salida estándar, pero la línea de comando
ls > outputredirecciona la salida estándar al archivo llamado "output" en el directorio actual. Similarmente, la línea de comando
mail mjb < letterabre el archivo "letter" como su entrada estándar y manda su contenido al usuario llamado "mjb". Los procesos pueden redireccionar la entrada y la salida simultáneamente, como en
nroff -mm < doc1 > doc1.out 2> errorsdonde el formateador de texto "nroff" lee el archivo de entrada "doc1", redirecciona su salida estándar al archivo "doc1.out" y redirecciona los mensajes de error al archivo "errors". Los programas ls, mail y nroff no saben que archivos serán su entrada, salida y error estándar; el shell reconoce los símbolos "<", ">" y "2>" y activa la entrada, la salida y error estándar apropiados antes de la ejecución de los procesos.
La segunda primitiva de bloque de construcción es la tubería o pipe, un mecanismo que permite a un flujo de datos ser pasado entre un procesos lectores y escritores. Los procesos pueden redireccionar su salida estándar a un pipe para ser leído por otro proceso que tiene redireccionada su entrada estándar desde el pipe. Los datos que el primer proceso escribe dentro del pipe es la entrada para el segundo proceso. El segundo proceso puede también redireccionar su salida, y así sucesivamente, dependiendo de las necesidades. Para indicar un pipe se usa el carácter "|". Por ejemplo, la línea de comando
grep main a.c b.c c.c | wc -lcuenta el número de líneas que contienen la cadena "main" en los archivos a.c, b.c y c.c (grep muestra las líneas en las que main aparece en los archivos y wc -l cuenta el número de líneas que tiene el archivo de entrada). De nuevo, los procesos no necesitan conocer que tipo de archivo es su salida estándar; trabajan prescindiendo de que su salida estándar sea un archivo regular, un pipe o un dispositivo. Cuando se usan pequeños programas como bloques de construcción para formar programas más grandes y complejos, el programador usa la primitiva pipe y el redireccionamiento de la entrada/salida para integrar las piezas. En realidad, el sistema fomenta un estilo de programación tal que nuevos programas pueden trabajar a partir de programas ya existentes. El uso de pipes frecuentemente hace innecesario la creación de archivos temporales.
El editor vi tiene dos modos de trabajo:
Pueden ser llamados varios archivos simultáneamente, pero sólo se edita uno de ellos en un momento determinado.
Al entrar a trabajar con el editor vi se borrará la pantalla y aparecerán las primeras 23 líneas del contenido del buffer. El signo tilde (~) indicará que la línea correspondiente está vacía. Cuando vi abre un archivo aparecerán en pantalla el número total de líneas del archivo, y el número total de caracteres. Si está protegido de escritura también lo indicará.
La edición no se realiza directamente sobre el archivo. Cuando se llama al editor, éste se asigna un buffer en memoria principal y copia sobre él el contenido del archivo (si ya existía). Todo el proceso de edición se realiza sobre este buffer.
En modo comando, no pueden ser introducidos datos en el buffer. Para ésto se deberá pasar a modo texto, que es la otra forma en que se puede trabajar el editor. Los únicos comandos que permite pasar a modo texto son: a, A, i, I, o, O, c (cada una de estas teclas tiene un significado distinto).
Una vez en modo texto las teclas son utilizadas para
introducir datos en el buffer del editor. Una vez que el texto ha sido introducido o modificado,
se estará en condiciones de volver al modo comando, pulsando para ello la tecla ESC. Si al
pulsar la tecla ESC suena la alarma, esto nos indicaría que ya se está en modo comando.
6.3 Modo dos puntos:
Se pasa a este modo desde el modo comando y pulsando el
carácter dos puntos (:). Este comando le indica al vi que se va a introducir a continuación un
comando del editor ed. Estos comandos aparecerán en la última línea de la pantalla. Para
ejecutar los comandos "dos puntos" es necesario finalizarlos con retorno de carro.
Este problema es solucionado en UNIX por un sistema (spool) que permite a diferentes usuarios enviar archivos a la impresora simultáneamente. Un conjunto de procesos, que se activan automáticamente durante la carga del sistema y el paso a multiusuario, se encarga de planificar las solicitudes creando una cola de impresión.
Cuando un usuario hace una solicitud de impresión, el planificador del sistema spool le contesta suministrando el número asignado a esa solicitud, e inmediatamente le devuelve el prompt, con lo que puede continuar con su trabajo aunque no se haya terminado de imprimir.
You have mailSi el receptor no estuviese conectado al sistema, el mensaje se almacenará en su buzón, y al usuario se le enviaría este mismo mensaje en el momento de la conexión ante el sistema.
El receptor no está obligado a leer el correo inmediatamente. Si no lo hace, el mensaje se repetirá periódicamente para recordarle que tiene correo en su buzón.
Este comando permite tanto el envío como la lectura de los
mensajes recibidos.
8.2 Write:
Message fromSi desea conectarse con ese usuario deberá enviarle un comando write. Una vez enviado, se establece comunicación directa entre ambos, por lo que se deberá establecer un protocolo que regule el envío mutuo de mensajes. El estandarizado es:
Broadcast Message from ...Suele ser frecuente su empleo como un sistema busca personas, o bien, para avisar a los usuarios de una inminente desconexión del sistema.
Este comando es más una herramienta del administrador del
sistema que de usuario.
8.4 News:
troff lee un archivo de entrada que contiene texto sin elaborar que va a ser formateado y produce con él un documento adecuadamente compuesto. Primero hay que preparar el archivo de entrada el editor que uno prefiera, luego se formatea el texto utilizando troff y posteriormente se le aplica el software de posproceso necesario para conseguir que la salida de troff se convierta en la adecuada para el dispositivo de impresión.
Asociados a troff se encuentran otros programas que realizan actividades más complicadas de tipografía como son la composición de tablas, tipografía matemática y los gráficos. Estos programas se denominan preprocesadores. Los más importantes son:
pic Programa que interpreta un lenguaje para describir
figuras.
tbl Programa que interpreta un lenguaje para describir
tablas.
eqn Programa que interpreta un lenguaje para describir
ecuaciones.
Todos estos programas se deben ejecutar con un determinado orden.