Next: La edición de ficheros
Up: Ficheros ejecutables
Previous: El control de procesos
En UNIX podemos invocar los comandos de dos formas diferentes: (1) en
foreground y (2) en background. La primera forma es la que
hemos usado hasta ahora en casi todas las ocasiones y se utiliza para
lanzar comandos interactivos desde el shell. Estos comandos se caracterizan
porque se ejecutan en poco tiempo y por tanto devuelven el control al shell
(que es el proceso que los ejecuta) rápidamente. Pero puede ocurrir que
ejecutemos procesos que tardan bastante tiempo en ejecutarse (en teoría
no hay límite: podemos hablar de meses) y no es agradable que el shell
se quede bloqueado hasta que el proceso acabe, más aún cuando no es
posible trabajar en modo multisesión. Así, podemos usar la ejecución
en background que proporciona el sistema operativo UNIX para lanzar
ese proceso pesado en paralelo con el resto de procesos que corren en el
sistema, entre los que evidentemente se encuentra el shell. Para lanzar
un proceso en background sólo tenemos que acabar el comando
interactivo con el metacarácter &. El siguiente ejemplo envía un
mail a un usuario llamado vruiz a la computadora
obelix.cica.es. Como sabemos que el mensaje que vamos a enviarle
es muy largo, podemos hacerlo en background y dejar que se envié
si que nos afecte prácticamente. Esto se hace así:
Cuando el sistema operativo termina de ejecutar el comando, este nos avisa
con el mensaje:
Lanzar procesos en background se complica un poco cuando estos
sacan mensajes en el terminal usando la salida estándar o la salida de
error estándar. Cuando esto ocurre, el proceso que corre en
background ensucia el terminal, lo que no es agradable, aunque este
es el único problema que presenta. De todas formas, muchas veces es
interesante que estas salidas puedan ser consultadas cuando el programa ha
finalizado, cosa que puede ocurrir dentro de un mes. En estos casos, las
salidas pueden redirigirse a un fichero o a un dispositivo. EL siguiente
ejemplo muestra como se utilizan la salida estándar y la salida de error
estándar desde un programa escrito en lenguaje C. Este se compila y se
muestra como se redireccionan cada una de las salidas.
Para compilar este programa sólo tenemos que invocar al compilador de C con
el nombre del fichero que deseamos compilar:
width 3pt
width .3pt415ptgogh: $ cc salidas.c
gogh: $
width .3pt
depth .3pt
width -3pt
El fichero ejecutable, ya que no hemos indicado lo contrario al compilador
se llama a.out y se ha creado en el directorio actual.
width 3pt
width .3pt415ptgogh: $ ls -l a.out
-rwxr-xr-x 1 vruiz wheel 4159 Feb 6 13:32 a.out
gogh: $
width .3pt
depth .3pt
width -3pt
Para ejecutarlo lo invocamos sencillamente si es que el camino . está
contemplado en nuestra variable de entorno $PATH. Supongamos que esto
es así:
width 3pt
width .3pt415ptgogh: $ a.out
he usado la salida estándar
he usado la salida de error estándar
gogh: $
width .3pt
depth .3pt
width -3pt
Ha ocurrido que ambas salidas aparecen en el terminal. Para redireccionarlas
usaremos los metaracaracteres de redirección que proporciona el shell.
Estos usan los pipes el UNIX. Si deseamos redireccionar la salida
estándar a un fichero escribiremos:
width 3pt
width .3pt415ptgogh: $ a.out > 1
he usado la salida de error estándar
gogh: $ cat 1
he usado la salida estándar
gogh: $
width .3pt
depth .3pt
width -3pt
Y si lo que deseamos es redirigir s'lo la salida de error estándar:
width 3pt
width .3pt415ptgogh: $ a.out 2> 1
he usado la salida estándar
gogh: $ cat 1
he usado la salida de error estándar
gogh: $
width .3pt
depth .3pt
width -3pt
Podemos redirigir ambas usando los dos redirectores simultaneamente:
width 3pt
width .3pt415ptgogh: $ a.out 2> 2 > 1
gogh: $ cat 1 2
he usado la salida estándar
he usado la salida de error estándar
gogh: $
width .3pt
depth .3pt
width -3pt
Por último, y lo que era nuesto objetivo, podemos lanzar el comando en
background, sin peligro de que el terminal se llene con los mensajes
de los procesos que corren en este modo:
Correr los procesos en background facilita la ejecución de trabajos
pesados, pero que ocurre si necesitamos avandonar el terminal y nuestro
proceso aún no ha acabado. Si hacemos el logout en estas condiciones
los procesos en background mueren porque muere el proceso padre que
los lanzó (el shell normalmente). Esto no es deseable y más cuando el
proceso ya lleva consumido muchas horas de CPU. Para resolver este problema
el sistema operativo dispone del comando nohup que permite evitar
este inconveniente. Su sintaxis:
-
- nohup {nombre_fichero_ejecutable}+ {args}*
nohup ejecuta un comando haciéndolo inmune a las señales de
finalización que pueda enviarse otro proceso. Además redirecciona la
salida a un fichero llamado nohup.out e incrementa la prioridad del
proceso en 5. Las salidas estándar y de error estándar se añaden a este
fichero. Si este no puede ser abierto para escritura, se intenta crear en
$HOMEnohup.out, y si esto falla, nohup falla (esto puede
ocurrir porque sobre ninguno de los directorios tengamos permiso de
escritura). El fichero nohup.out se crea sin permisos para el resto
de usuarios (-rw----), pero si ya existía los permisos se
respetan. Por último, decir que nohup no pone automáticamente el
comando en background sino que hay que hacerlo explícitamente como
ya se ha indicado. Un ejemplo:
Next: La edición de ficheros
Up: Ficheros ejecutables
Previous: El control de procesos
Vicente González Ruiz
1998-07-13