1.  PROCESOS UNIX Y UN FICHERO LLAMADO .profile


1.1  Procesos

Un proceso es la ejecución de un comando por UNIX.  Los procesos pueden
también ser ejecutados por el sistema operativo en si.  Al igual que la
estructura de ficheros, la estructura de procesos es jerárquica.
Contiene padres, hijos e incluso una raíz.  Un padre puede bifurcar (o
engendrar) un proceso hijo.  Ese hijo puede, a su vez, bifurcar otros
procesos. La primer cosa que el sistema operativo hace para comenzar la
ejecución es crear un proceso simple, PID número 1.  PID sigfnica
Identificador de Proceso.  Este proceso mantendrá la misma posición que
el directorio raiz en la estructura de ficheros.  Este proceso es el
ancestro de todos los procesos en los que trabaja cada usuario.  Bifurca
un proceso para cada terminal.  Cada uno de estos procesos se convierte
en proceso de Shell cuando el usuario se loguea.



1.2 Identificación de Procesos


El sistema operativo UNIX asigna un número de proceso único (PID) a cada
proceso.  Mantendrá el mismo PID en tanto el proceso viva.  Durante una
sesión, el mismo proceso siempre se ejecuta en la shell de login.
Cuando ejecutas otro comando, un nuevo proceso se bifurcará, y se le
asignará un nuevo PID a dicho proceso.  Cuando el mencionado proceso
hijo finalice, se lo devolverá al proceso de login, que se está
ejecutando en la shell, y ese proceso padre tiene el mismo PID que
cuando se logueó.


La shell almacena la PID en la variable de shell llamada $$.  El PID
también puede consultarse con el comando de status de proceso (ps).  El
formato de ps es el siguiente:


+===============================================================+
|    Command Format:  ps [options]                              |
|                                                               |
|    See on-line manual for options                             |
+===============================================================+

Si no se dan opciones, el comando ps le dará cierta información sobre
los procesos asociados con el control de la terminal.  La salida
consiste en un listado corto que contiene el id de proceso, el id de
terminal, el tiempo de ejecución acumulado, y el nombre del comando.  De
otro modo, las opciones controlarán la pantalla.

Sesión de ejemplo:

+----------------------------------------------------------------------------+
| $echo $$                                                                   |
| 8347                                                                       |
| $ps                                                                        |
|    PID TTY      TIME COMMAND                                               |
|   8347 rt021a0  0:03 ksh                                                   |
|   8376 rt021a0  0:06 ps                                                    |
| $                                                                          |
+----------------------------------------------------------------------------+


Los números PID de la shell son los mismos en la sesión de ejemplo
puesto que la shell sustituirá su propio número por el $$.  La shell
hace la sustitución antes de que bifurque un nuevo proceso para ejecutar
el comando echo.  Por lo tanto, echo mostraraá el núimero de PID del
proceso que lo llamó, no el PID del proceso que está ejecutando. La
opción -l mostrará más información sobre los procesos.


Sesión de Ejemplo:

+------------------------------------------------------------------------------------------+
| $ps -l                                                                                   |
|     F S   UID   PID  PPID  C PRI NI     ADDR     SZ    WCHAN TTY      TIME COMD          |
| f0000 S   115  8347   309  2  30 20  1009000    140    94014 rt021a0  0:03 ksh           |
| f0000 O   115  8386  8347 16  68 20  1308000     72          rt021a0  0:01 ps            |
| $ps -l                                                                                   |
|     F S   UID   PID  PPID  C PRI NI     ADDR     SZ    WCHAN TTY      TIME COMD          |
| f0000 S   115  8347   309  1  30 20  1009000    140    94014 rt021a0  0:03 ksh           |
| f0000 O   115  8387  8347 26  73 20  1146000     72          rt021a0  0:01 ps            |
| $                                                                                        |
+------------------------------------------------------------------------------------------+



1.3  Ejecutando un Comando


Cuando introduce un comando al Shell, para ejecutar el comando este
bifurcará un proceso. Mientras el proceso hijo está ejecutando el
comando, el proceso padre se pondrá en reposo. El reposo ("sleep")
significa que el proceso no utilizará ciclos de CPU. Permanecerá
inactivo hasta que se lo despierte. Cuando el proceso hijo haya
terminado de ejecutar el comando, se apagará. El proceso padre, que está
ejecutando el Shell, se reactivará y quedará a la espera de su sulicitud
de ejecución de otro comando.

Cuando solicite que un proceso se ejecute en segundo plano (al finalizar
la línea de comando con un carácter &), el Shell bifurca un proceso hijo
al que se le permite ejecutarse hasta completarse. El proceso padre
informará el PID del proceso hijo y luego te solicitará otro comando. El
proceso hijo y el proceso padre ahora son procesos independientes.



1.4  Los comandos . (punto) y exec

Hay dos maneras de ejecutar un programa sin bifurcar un nuevo proceso.
El comando . (punto) ejecutará el guión como parte del proceso actual.
Cuando el nuevo guión haya finalizado su ejecución, el proceso actual
continuará ejecutando el guión original.  El comando exec ejecutará el
nuevo guión en lugar del guión original (overlay), y nunca retornará al
guión original.

El comando . (punto) no ejecutará ficheros compilados (binarios) y no
requiere permisos de ejecución en el fichero del guión que va a
ejecutarse. El comando exec no requiere permisos de acceso no al
programa binario ni a un guión de shell.


Sesión de ejemplo:

+---------------------------------------------------------------+
|    $ls -l prog2                                               |
|    -rw-r--r--  1 profesor  clase   22 Jan 18 10:30 prog2      |
|    $cat prog2                                                 |
|    echo 'prog2 PID =' $$                                      |
|    $cat dot_example                                           |
|    echo $0 'PID=' $$                                          |
|    . prog2                                                    |
|    echo 'Esta línea se ejecutó'                               |
|    $ejemplo_punto                                             |
|    ejemplo_punto PID= 6942                                    |
|    prog2 PID = 6942                                           |
|    Esta línea se ejecutó                                      |
|    $                                                          |
+---------------------------------------------------------------+

El comando exec se superpondrá al comando sh y el control nunca volverá
al script que lo llamó. Veamos otro ejemplo con una llamada a prog2
usando exec en lugar de . (punto):

Sesión de ejemplo:

+---------------------------------------------------------------+
|    $ls -l prog2                                               |
|    -rwxr-xr-x  1 profesor  clase   22 Jan 18 10:30 prog2      |
|    $cat prog2                                                 |
|    echo 'prog2 PID =' $$                                      |
|    $cat exec_example                                          |
|    echo $0 'PID=' $$                                          |
|    exec prog2                                                 |
|    echo 'Esta línea nunca se ejecutará'                       |
|    $exec_example                                              |
|    exec_example PID= 6950                                     |
|    prog2 PID = 6950                                           |
|    $                                                          |
|                                                               |
+---------------------------------------------------------------+

Procesamiento en segundo plano

Cuando un programa se ejecuta en segundo plano, no es necesario esperar
a que finalice antes de iniciar otro programa. Esto resulta útil porque
puede iniciar trabajos largos o de gran tamaño y luego continuar con
otra tarea en su terminal.

Para ejecutar un programa en segundo plano, simplemente escriba el
carácter & al final de la línea de comandos antes de la tecla (Ret). El
Shell devolverá el PID del proceso en segundo plano y luego le mostrará
otro mensaje del sistema.

Sesión de ejemplo:

+---------------------------------------------------------------+
|    $ls -l | lp &                                              |
|    [1]     21334                                              |
|    $request id is mt_600-2736 (standard input)                |
|                                                               |
|    $                                                          |
+---------------------------------------------------------------+

Si la tarea en segundo plano envía la salida a la salida estándar y no
logra redirigirla, la salida aparecerá en su terminal incluso si está
ejecutando otro programa en ese momento.

Es necesario utilizar el comando kill para detener un proceso que se
está ejecutando en segundo plano; la tecla (DEL) o su equivalente no
funcionará.


Status de salida

Cuando un proceso deja de ejecutarse por cualquier motivo, devolverá un
estado de salida al proceso principal. Este estado de salida también se
conoce como código de condición o código de retorno. El Shell almacena
el estado de salida en una variable de Shell llamada $?. Por convención,
un estado de salida distinto de cero significa que tiene un valor falso
y que el comando falló. Por otro lado, un estado cero indica que es
verdadero y que el comando se realizó correctamente.

Es posible especificar el estado de salida cuando sale de un script.
Esto se hace especificando el número que se utilizará como estado de
salida mediante el comando exit. El siguiente script es un ejemplo:

Sesión de ejemplo:

+---------------------------------------------------------------+
|    $cat ejemplo_salida                                        |
|    echo 'Este programa deuvelve un status de salida'          |
|    echo 'de 7.'                                               |
|    exit 7                                                     |
|    $ejemplo_salida                                            |
|    Este programa devuelve un status de salida                 |
|    de 7.                                                      |
|    $echo $?                                                   |
|    7                                                          |
|    $echo $?                                                   |
|    0                                                          |
|    $                                                          |
|                                                               |
+---------------------------------------------------------------+

Este script mostrará el mensaje y luego saldrá con un código de salida
de 7. El estado de salida se almacena en la variable de Shell llamada
$?. El segundo comando echo anterior muestra el estado de salida del
primer comando echo. Dado que se completó correctamente, tiene un valor
de cero.



1.4 Manejo de interrupciones


Una señal es un informe a un proceso sobre una condición. UNIX usa estas
señales para informar sobre llamadas de sistema incorrectas, tuberías
rotas, instrucciones ilegales y otras condiciones. Hay tres señales que
son útiles al programar en el Shell. Son la señal de interrupción de
terminal (número 2), la señal kill (número 9) y la señal de terminación
de software (número 15).

Puede usar el comando trap para capturar una señal y luego realizar la
acción que especifique. Puede cerrar archivos o finalizar otro
procesamiento que se deba realizar, mostrar un mensaje, finalizar la
ejecución de inmediato o ignorar la señal.

+===============================================================+
|   Command Format: trap ['commands'] signal_numbers            |
|                                                               |
|   See online man pages for details                            |
|                                                               |
+===============================================================+

Los signal_numbers ("números de señal") son los números correspondientes
a las señales que serán atrapadas por el comando trap. Debe haber al
menos un número presente. La parte 'comandos' del comando es opcional.
De no estar presente, el comando restablece el trap a su condición
inicial, que es salir del programa. Cuando los comandos están presentes,
el Shell ejecuta los comandos cuando captura una de las señales. Después
de ejecutar los comandos, el Shell continúa ejecutando el script donde
lo dejó.

Puede interrumpir un programa que esté ejecutando en primer plano
presionando la tecla Eliminar. Cuando presiona esta tecla, se envía una
señal (número 2), una interrupción de terminal, al programa. El Shell
terminará la ejecución del programa si el programa no atrapa la señal.
El siguiente ejemplo demuestra el comando trap que atrapará la señal y
devolverá un estado de salida de 1.

Sesión de ejemplo:

+---------------------------------------------------------------+
|    $cat inter                                                 |
|    trap 'echo PROGRAMA INTERRUMPIDO; exit 1' 2                |
|    while (true)                                               |
|          do                                                   |
|          echo 'Programa ejecutando'                           |
|          done                                                 |
|    $                                                          |
+---------------------------------------------------------------+

La primera línea de inter establece una trampa para la señal número 2,
la interrupción de terminal. Cuando se captura la señal, el Shell
ejecutará los comandos entre las dos comillas simples. En este ejemplo,
el comando echo mostrará PROGRAMA INTERRUMPIDO. El comando exit
devolverá el control al Shell y se mostrará un mensaje de aviso del
sistema. Si no se mostrara el mensaje de aviso, el control volvería al
bucle while después de mostrar el mensaje.

Puede enviar una terminación de software a un proceso en segundo plano
utilizando el comando kill sin un número de señal. Sin embargo, se puede
configurar un comando trap para capturar esta señal (número 15). Se
puede enviar una señal kill para matar un proceso con un número de señal
9 y el Shell no puede capturar una señal kill.


El archivo llamado .profile

El Bourne Shell declara e inicializa variables que determinan cosas como
su directorio personal, en qué directorios buscará el Shell cuando dé
comandos, con qué frecuencia buscar correo, el mensaje de aviso del
sistema y muchas otras cosas. Veremos algunas de estas variables del
Shell y sus funciones. Puede asignar nuevos valores a estas variables
desde la línea de comandos o ejecutando el contenido de un archivo
llamado .profile. BourneShell ejecuta los comandos de este archivo en el
mismo entorno que el Shell cada vez que el usuario inicia sesión. El
profile debe estar en el directorio de inicio del usuario. Cada usuario
tiene un .profile diferente. Generalmente especifica el tipo de terminal
y establece las características del terminal y otras funciones de
mantenimiento según lo requiera el usuario.



1.5 INICIO


La primera variable de BourneShell que veremos es la variable HOME. De
manera predeterminada, el directorio de inicio es el directorio de
trabajo actual después de iniciar sesión. El administrador del sistema
determina su directorio de inicio cuando establece una cuenta y coloca
esa información en el archivo /etc/passwd. Cuando inicia sesión,
BourneShell obtiene esa ruta y la asigna a la variable HOME.

Cuando ingresa un comando cd sin argumentos, la utilidad toma el nombre
del directorio de la variable HOME y lo convierte en el directorio de
trabajo actual. Si cambia la variable HOME a otra ruta de directorio, la
utilidad hará que el nuevo directorio sea el directorio de trabajo
actual.



Sesión de Ejemplo:

+---------------------------------------------------------------+
| $echo $HOME                                                   |
| /user0/rharding                                               |
| $cd                                                           |
| $pwd                                                          |
| /user0/rharding                                               |
| $HOME=/user0/rharding/eng                                     |
| $cd                                                           |
| $pwd                                                          |
| /user0/rharding/eng                                           |
| $                                                             |
+---------------------------------------------------------------+

Este ejemplo muestra cómo el valor de la variable HOME afecta a la
utilidad cd. El comando cd utilizará el valor de la variable HOME como
la ruta de acceso para el directorio de trabajo actual.



1.6 PATH


Esta variable de BourneShell describirá los directorios en los que se
realizará la búsqueda para encontrar el programa que desea ejecutar.
BourneShell busca en varios directorios un archivo que tenga el mismo
nombre que el comando que ingresó. La variable PATH controla esta ruta
de búsqueda. Normalmente, el primer directorio buscado es el directorio
de trabajo actual. Si no se encuentra el programa, la búsqueda continúa
en el directorio /bin y luego en el directorio /usr/bin. Generalmente,
estos directorios contienen programas ejecutables. Si no se encuentra el
programa en uno de estos directorios, BourneShell informa que no se
puede encontrar (o ejecutar) el programa.

La variable PATH enumera las rutas de acceso en el orden en el que se
realizará la búsqueda. Las rutas de acceso están separadas por dos
puntos (:). Si no hay nada (cadena nula) antes de los dos puntos, eso
indica que se debe iniciar la búsqueda en el directorio de trabajo
actual.

Ejemplo:

Este ejemplo muestra cómo el valor de la variable HOME afecta a la
utilidad cd. El comando cd utilizará el valor de la variable HOME como
la ruta de acceso para el directorio de trabajo actual.

................................................................
$PATH=:/user0/rharding/bin:/bin:/usr/bin                      .
$                                                             .
................................................................

Esta variable PATH indica que se debe iniciar la búsqueda del programa
en el directorio de trabajo actual, luego buscar en el directorio
/user0/rharding/bin, luego /bin y finalmente /usr/bin.

Si cada usuario tiene una ruta única especificada, cada usuario puede
ejecutar un programa diferente dando el mismo comando. La búsqueda del
programa se detiene cuando se satisface; por lo tanto, puede usar el
mismo nombre para sus propios programas que las utilidades estándar de
UNIX. Para hacer esto, simplemente coloque su programa en uno de los
primeros directorios que busca BourneShell.



1.7 Variables de entorno de INGRES


Hay algunas variables de entorno que deben estar en el .profile que
configura INGRES. Los siguientes ejemplos se dan como pautas generales,
no como entradas reales que se deben realizar en su .profile.



1.8 ING_HOME


Este es el directorio de inicio de INGRES. Esta variable es válida para
la versión 5 de INGRES. Esta variable se configura de la siguiente
manera.

Ejemplo:

................................................................
   $ING_HOME=/user5/ingres                                    .
................................................................

Tenga en cuenta que esta variable de entorno está escrita en mayúsculas.
Esto es un requisito en UNIX.



1.9 TERM_INGRES


Si no se configura esta variable, INGRES utilizará el tipo de terminal
predeterminado definido por la variable TERM en UNIX. No es obligatorio,
pero se pueden experimentar dificultades para utilizar el menú principal
de INGRES si no se utiliza.

Ejemplo:

................................................................
   $TERM_INGRES=vt100f                                        .
................................................................



1.10 ING_EDIT


Esta variable define el editor que se utilizará cada vez que un usuario
introduzca un comando que requiera el uso de un editor. El valor
predeterminado es utilizar el editor "ed".

Ejemplo:

................................................................
  $ING_EDIT=/usr/bin/vi                                       .
................................................................









Trabajo Práctico 1


Este trabajo práctico reforzará su comprensión del material presentado
en este capítulo. Inicie sesión con el nombre de usuario y la contraseña
que le proporcionó el instructor. Cada estudiante debe completar todo el
taller.


EJERCICIOS DE ESCRITORIO

1. ¿Cuál es el nombre del archivo que se ejecuta desde su directorio
personal cada vez que inicia sesión?

2. ¿Qué representa la variable de Shell HOME?

3. ¿Qué representa la variable de Shell PATH?

4. ¿Qué es un proceso UNIX?

5. Cuando se le da un comando a Shell, este bifurcará un proceso
secundario para ejecutar el comando.

Verdadero/Falso

6. ¿Qué es un número de identificación de proceso (PID)?

7. ¿Cuál es el propósito del comando trap?


EJERCICIOS DE COMPUTADORA

8. Inicie su sesión

9. ¿Cuál es el PID de su proceso?

10. Edite el .profile para incluir su directorio personal en la ruta.

11. Modifique el archivo .profile para que cada vez que inicie sesión se
muestre una lista de los archivos en su directorio de trabajo actual
(HOME).

12. Envíe una lista larga de todos los archivos en el directorio de
trabajo actual a la impresora predeterminada y hágalo en segundo plano.

13. Cierre la sesión


NOTAS

===========================================