next up previous
Next: La edición de ficheros Up: Ficheros ejecutables Previous: El control de procesos

Usando del background

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 up previous
Next: La edición de ficheros Up: Ficheros ejecutables Previous: El control de procesos
Vicente González Ruiz
1998-07-13