% Instalaci\'on y Comienzo en Linux
% job-control.tex
% Copyright (c) 1992, 1993 by Matt Welsh, Larry Greenfield and Karl Fogel
%
% Este documento puede ser libremente distribuido, pero se deber preservar
% este Copyright y solo podr\'a ser distribuido como una parte del Linux

% Traduccion realizada por Luis Ram\'on Duarte. Envie sus comentarios a:
%            Luis Ram\'on Duarte Madail, 2:346/13.11 (FidoNet)
% $Log: job-control.tex,v $
% Revision 0.5.0.1  1996/02/10 23:45:15  rcamus
% Primera beta publica
%
%

\section{Control de Tareas}\label{sec-job-control}

\index{control de tareas|(}
\subsection{Tareas y procesos}
\label{sec-process}\label{sec-processes}
\index{shells!control de tareas proporcionado por}

{\bf Control de Tareas} es una utilidad incluida en muchos shells (incluidas
Bash y Tcsh), que permite el control de multitud de comandos o {\bf tareas}
al momento. Antes de seguir, deberemos hablar un poco sobre los {\bf procesos}.

\index{procesos!defined}
\index{ps@{\tt ps}}
\index{procesos!ps para listar@{\tt ps} para listar}

Cada vez que usted ejecuta un programa, usted lanza lo que se conoce
como {\em proceso}, que es simplemente el nombre que se le da a un programa
cuando se esta ejecutando. El comando {\tt ps} visualiza la lista de 
procesos que se est\'an ejecutando actualmente, por ejemplo:

\begin{tscreen}
/home/larry\# {\em ps}
\begin{verbatim}
  PID TT STAT  TIME COMMAND
   24  3 S     0:03 (bash)
  161  3 R     0:00 ps
\end{verbatim}
/home/larry\#
\end{tscreen}
\index{procesos!ID!defined}
La columna {\tt PID} representa el {\bf identificador de proceso}. La 
\'ultima columna {\tt COMMAND}, es el nombre del proceso que se est\'a 
ejecutando. Ahora solo estamos viendo los procesos que est\'a ejecutando 
Larry\footnote{Hay muchos m\'as procesos aparte de estos corriendo en el 
sistema, para verlos todos, teclearemos el comando ``{\tt ps -aux}''.}.
Vemos que hay dos procesos, {\tt bash} (Que es el shell o int\'erprete de
comandos que usa Larry), y el propio comando {\tt ps}. Como puede observar,
la {\tt bash} se ejecuta concurrentemente con el comando {\tt ps}. La {\tt
bash} ejecut\'o {\tt ps} cuando Larry tecle\'o el comando. Cuando {\tt ps}
termina de ejecutarse (despu\'es de mostrar la tabla de procesos), el control
retorna al proceso {\tt bash}, que muestra el prompt, indicando que est\'a
listo para recibir otro comando.

\index{tarea!defined}
Un proceso que esta corriendo se denomina {\em tarea\/} para el shell.
Los t\'erminos {\em proceso\/} y {\em tarea\/}, son intercambiables. Sin 
embargo, se suele denominar ``tarea'' a un proceso, cuando es usado en 
conjunci\'on con {\bf control de tareas}, que es un rasgo del shell que 
permite cambiar entre distintas tareas.

En muchos casos, los usuarios solo ejecutan un trabajo cada vez, que es el
\'ultimo comando que ellos teclearon desde el shell. Sin embargo, usando el
control de tareas, usted podr\'a ejecutar diferentes tareas al mismo tiempo,
cambiando entre cada uno de ellos conforme lo necesite. ?`Cu\'an beneficioso
puede llegar a ser esto?. Supongamos que est\'a usted con su procesador de
textos, y de repente necesita parar y realizar otra tarea, con el control de
tareas, usted podr\'a suspender temporalmente el editor, y volver al shell
para realizar cualquier otra tarea, y luego regresar al editor como si no lo
hubiese dejado nunca. Lo siguiente solo es un ejemplo, hay montones de usos
pr\'acticos del control de tareas.

\subsection{Primer plano y Segundo plano}

\index{procesos!primer plano}
\index{procesos!segundo plano}
\index{tarea!primer plano}
\index{tarea!segundo plano}
\index{proceso en primer plano}
\index{proceso en segundo plano}

Un proceso puede estar en {\bf Primer plano} o en {\bf Segundo plano}. Solo
puede haber un proceso en primer plano al mismo tiempo, el proceso que est\'a
en primer plano, es el que interact\'ua con usted---recibe entradas de
teclado, y env\'{\i}a las salidas al monitor. (Salvo, por supuesto, que haya
redirigido la entrada o la salida, como se describe en la
Secci\'on~\ref{sec-plumbing}). El proceso en segundo plano, no recibe
ninguna se\~nal desde el teclado---por lo general, se ejecutan en silencio sin
necesidad de interacci\'on.

Algunos programas necesitan mucho tiempo para terminar, y no hacen nada
interesante mientras tanto. Compilar programas es una de estas tareas, 
as\'{\i} como comprimir un fichero grande. No tiene sentido que se siente 
y se aburra mientras estos procesos terminan. En estos casos es mejor 
lanzarlos en segundo plano, para dejar el ordenador en condiciones de 
ejecutar otro programa.

\index{tarea!suspendido}
Los procesos pueden ser {\bf suspendidos}. Un proceso suspendido es aquel
que no se est\'a ejecutando actualmente, sino que est\'a temporalmente parado.
Despu\'es de suspender una tarea, puede indicar a la misma que contin\'ue, en
primer plano o en segundo, seg\'un necesite. Retomar una tarea suspendida no
cambia en nada el estado de la misma---la tarea continuar\'a ejecutandose
justo donde se dej\'o.

\index{procesos!interrumpir}
\index{tareas!interrumpir}
Tenga en cuenta que suspender un trabajo no es lo mismo que {\em
interrumpirlo\/}. Cuando usted interrumpe un proceso (generalmente con la
pulsaci\'on de \key{ctrl-C}\footnote{La tecla de interrupci\'on puede definirse
usando el comando {\tt stty}. Por defecto, en la mayor\'{\i}a de sistemas es
\key{ctrl-C}, pero no se puede garantizar que sea la misma en su sistema.}),
el proceso muere, y deja de estar en memoria y utilizar recursos del 
ordenador. Una vez eliminado, el proceso no puede continuar ejecutandose, y
deber\'a ser lanzado otra vez para volver a realizar sus tareas. Tambi\'en se
puede dar el caso de que algunos programas capturan la interrupci\'on, de modo
que pulsando \key{ctrl-C} no se para inmediatamente. Esto se hace para
permitir al programa realizar operaciones necesarias de limpieza antes de
terminar\footnote{Tiempo necesario para guardar algunos registros, etc.}.
De hecho, algunos programas simplemente no se dejan matar por ninguna
interrupci\'on.

\subsection{Env\'{\i}o a segundo plano y eliminaci\'on de procesos}

Empecemos con un ejemplo sencillo. El comando {\tt yes} es un comando
aparentemente in\'util que env\'{\i}a una serie interminable de {\tt y}-es a la
salida est\'andar. (Realmente es muy \'util. Si se utiliza una 
tuber\'{\i}a (o ``pipe'') para unir la salida de {\tt yes} con otro comando 
que haga preguntas del tipo si/no, la serie de {\tt y}-es confirmar\'a 
todas las preguntas.)

Pruebe con esto.
\begin{tscreen}
/home/larry\# {\em yes} \\
y \\
y \\
y \\
y \\
y
\end{tscreen}
\index{procesos!kill}
\index{procesos!interrupci\'on}
\index{tareas!matar}
\index{tareas!interrupci\'on}

La serie de {\tt y}-es continuar\'a hasta el infinito, a no ser que usted la
elimine, pulsando la tecla de interrupci\'on, generalmente \key{ctrl-C}.
Tambi\'en puede deshacerse de esta serie de {\tt y}-es redigiriendo la salida
est\'andar de {\tt yes} hacia {\tt /dev/null}, que como recordar\'a es una
especie de ``agujero negro'' o papelera para los datos. Todo lo que usted
env\'{\i}e all\'{\i}, desaparecer\'a.
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null}
\end{tscreen}
Ahora va mucho mejor, el terminal no se ensucia, pero el prompt de la shell
no retorna. Esto es porque {\tt yes} sigue ejecutandose y enviando esos
in\'utiles {\tt y}-es a {\tt /dev/null}. Para recuperarlo, pulse la tecla de
interrupci\'on.

Supongamos ahora que queremos dejar que el comando {\tt yes} siga
ejecutandose, y volver al mismo tiempo a la shell para trabajar en otras
cosas. Para ello nos enviaremos a {\tt yes} a segundo plano, lo que nos
permitir\'a ejecutarlo, pero sin necesidad de interacci\'on.

\index{tarea!segundo plano}
\index{mandando tareas a segundo plano}
Una forma de mandar procesos a segundo plano es a\~nadiendo un car\'acter 
``{\tt \&}'' al final de cada comando.
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null \&} \\
\verb+[1] 164+ \\
/home/larry\#
\end{tscreen}
Como podr\'a ver, ha regresado a la shell. ?`Pero qu\'e es eso de ``{\tt \verb+[1]
164+}''?, ?`se est\'a ejecutando realmente el comando {\tt yes}?

``{\tt \verb+[1]+}'' representa el {\bf n\'umero de tarea} del proceso {\tt
yes}. La shell asigna un n\'umero a cada tarea que se est\'e ejecutando. Como
{\tt yes} es el \'unico comando que se est\'a ejecutando, se le asigna el 
n\'umero de tarea {\tt 1}. El n\'umero ``{\tt 164}'' es el n\'umero de 
identificaci\'on del proceso, o PID, que es el n\'umero que el sistema le 
asigna al proceso. Ambos n\'umeros pueden usarse para referirse a la 
tarea como veremos despu\'es.

\index{tareas@{\tt jobs}}
Ahora usted tiene el proceso {\tt yes} corriendo en segundo plano, y enviando
constantemente la se\~nal {\tt y} hacia el dispositivo {\tt
/dev/null}. Para
chequear el estado del proceso, utilice el comando interno de la shell {\tt
jobs}:
\begin{tscreen}
/home/larry\# {\em jobs} \\
\verb-[1]+  Running                 yes >/dev/null  &- \\
/home/larry\#
\end{tscreen}

!`Ah\'{\i} est\'a!. Tambi\'en puede usar el comando {\tt ps}, como mostramos 
antes, para comprobar el estado de la tarea.

\index{matar@{\tt kill}}
\index{procesos!segundo plano!matar}
\index{tarea!segundo plano!matar}
Para eliminar una tarea, utilice el comando {\tt kill}.
Este comando toma como argumento un n\'umero de tarea o un n\'umero de ID de un
proceso. Esta era la tarea 1, as\'{\i} que usando el comando
\begin{tscreen}
/home/larry\# {\em kill \%1}
\end{tscreen}
matar\'a la tarea. Cuando se identifica la tarea con el n\'umero de tarea, se
debe preceder el n\'umero con el car\'acter de porcentaje (`{\tt \%}'').

Ahora que ya hemos matado la tarea, podemos usar el comando {\tt jobs} de
nuevo para comprobarlo:
\begin{tscreen}
/home/larry\# {\em jobs}
\begin{verbatim}
[1]+  Terminated              yes >/dev/null
\end{verbatim}
/home/larry\#
\end{tscreen}

La tarea est\'a, en efecto, muerta, y si usa el comando {\tt jobs} de nuevo,
no mostrar\'a nada.

Tambi\'en podr\'a matar la tarea usando el n\'umero de ID de proceso 
(PID), el cual se muestra conjuntamente con el ID de tarea cuando arranca 
la misma. En nuestro ejemplo el ID de proceso es 164, as\'{\i} que el comando
\begin{tscreen}
/home/larry\# {\em kill 164}
\end{tscreen}
es equivalente a
\begin{tscreen}
/home/larry\# {\em kill \%1}
\end{tscreen}

No es necesario usar el ``{\tt \%}'' cuando nos referimos a una tarea a
trav\'es de su ID de proceso.

\subsection{Parada y relanzamiento de tareas}
\index{tarea!parada}
Hay otra manera de poner una tarea en segundo plano. Usted puede lanzarlo
como un proceso normal (en primer plano), pararlo, y despu\'es relanzarlo en
segundo plano.

Primero, lance el proceso {\tt yes} en primer plano como lo har\'{\i}a normalmente:
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null}
\end{tscreen}

De nuevo, dado que {\tt yes} corre en primer plano, no debe retornar el
prompt de la shell.

Ahora, en vez de interrumpir la tarea con \key{ctrl-C}, {\em
suspenderemos} la tarea. El suspender una tarea no la mata: solamente la
detiene temporalmente hasta que Ud. la retoma. Para hacer esto usted debe
pulsar la tecla de suspender, que suele ser \key{ctrl-Z}.
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null} \\
\key{ctrl-Z} \\
\verb-[1]+  Stopped                 yes >/dev/null- \\
/home/larry\#
\end{tscreen}

Mientras el proceso est\'a suspendido, simplemente no se esta ejecutando.
No gasta tiempo de CPU en la tarea. Sin embargo, usted puede retomar el
proceso de nuevo como si nada hubiera pasado. Continuar\'a ejecutandose donde
se dej\'o.

\index{fg@{\tt fg}}
\index{tarea!relanzamiento}
Para relanzar la tarea en primer plano, use el comando {\tt fg} (del ingl\'es
``foreground'').
\begin{tscreen}
/home/larry\# {\em fg} \\
yes >/dev/null
\end{tscreen}
\index{tarea!segundo plano}
\index{bg@{\tt bg}}

La shell muestra el nombre del comando de nuevo, de forma que tenga
conocimiento de que tarea es la que ha puesto en primer plano. Pare la tarea
de nuevo, con \key{ctrl-Z}. Esta vez utilice el comando {\tt bg} para poner
la tarea en segundo plano. Esto har\'a que el comando siga ejecutandose igual
que si lo hubiese hecho desde el principio con ``{\tt \&}'' como en la
secci\'on anterior.
\begin{tscreen}
/home/larry\# {\tt bg} \\
\verb-[1]+- yes >/dev/null  \& \\
/home/larry\#
\end{tscreen}

Y tenemos de nuevo el prompt. El comando {\tt jobs} deber\'{\i}a decirnos que {\tt
yes} se est\'a ejecutando, y podemos matar la tarea con {\tt kill} tal y como
lo hicimos antes.

?`C\'omo podemos parar la tarea de nuevo? Si pulsa \key{ctrl-Z} no funcionar\'a,
ya que el proceso est\'a en segundo plano. La respuesta es poner el proceso en
primer plano de nuevo, con el comando {\tt fg}, y entonces pararlo. Como
puede observar podr\'a usar {\tt fg} tanto con tareas detenidas, como con las
que est\'en segundo plano.

Hay una gran diferencia entre una tarea que se encuentra en segundo plano,
y una que se encuentra detenida. Una tarea detenida es una tarea que no se
est\'a ejecutando, es decir, que no usa tiempo de CPU, y que no est\'a haciendo
ning\'un trabajo (la tarea aun ocupa un lugar en memoria, aunque puede ser
volcada a disco). Una tarea en segundo plano, se est\'a ejecutando, y usando
memoria, a la vez que completando alguna acci\'on mientras usted hace otro
trabajo. Sin embargo, una terea en segundo plano puede intentar mostrar
texto en su terminal, lo que puede resultar molesto si est\'a intentando hacer
otra cosa. Por ejemplo, si usted us\'o el comando
\begin{tscreen}
/home/larry\# {\em yes \&}
\end{tscreen}
sin redirigir stdout a {\tt /dev/null}, una cadena de {\tt y}-es se
mostrar\'an en su monitor, sin modo alguno de interrumpirlo (no puede hacer
uso de \key{ctrl-C} para interrumpir tareas en segundo plano). Para poder
parar esas interminables {\tt y}-es, tendr\'{\i}a que usar el comando {\tt fg}
para pasar la tarea a primer plano, y entonces usar \key{ctrl-C} para matarla.

Otra observaci\'on. Normalmente, los comandos ``fg'' y ``bg'' act\'uan sobre el
\'ultimo proceso parado (indicado por un ``{\tt +}'' junto al n\'umero de tarea
cuando usa el comando {\tt jobs}). Si usted tiene varios procesos corriendo
a la vez, podr\'a mandar a primer o segundo plano una tarea espec\'{\i}fica
indicando el ID de tarea como argumento de {\tt fg} o {\tt bg}, como en
\begin{tscreen}
/home/larry\# {\em fg \%2}
\end{tscreen}
(para la tarea de primer plano n\'umero 2), o
\begin{tscreen}
/home/larry\# {\em bg \%3}
\end{tscreen}
(para la tarea de segundo plano n\'umero 3). No se pueden usar los ID de
proceso con {\tt fg} o {\tt bg}.

Adem\'as de esto, si usa el n\'umero de tarea por si solo, como
\begin{tscreen}
/home/larry\# {\em \%2}
\end{tscreen}
es equivalente a
\begin{tscreen}
/home/larry\# {\em fg \%2}
\end{tscreen}

Solo recordarle que el uso de control de tareas es una utilidad de la
shell. Los comandos {\tt fg}, {\tt bg} y {\tt jobs} son internos de la
shell. Si por alg\'un motivo usted utiliza una shell que no soporta control de
tareas, no espere disponer de estos comandos.

Y adem\'as, hay algunos aspectos del control de tareas que difieren entre
Bash y Tcsh. De hecho, algunas shells no proporcionan ning\'un control de
tareas---sin embargo, la mayor\'{\i}a de las shells disponibles para Linux
soportan control de tareas.

\index{control de tareas|)}
