Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Términos y utilidades
• &
• bg
• fg
• jobs
• kill
• nohup
• ps
• top
• free
• uptime
103.5.1. Introducción.
El objetivo principal es la gestión básica de procesos en Linux. Los principales apartados
del mismo son los siguientes:
Linux es un sistema operativo multitarea y multiusuario. Esto quiere decir que múltiples
procesos pueden operar simultáneamente sin interferirse unos con los otros. Cada proceso
cree que es el único en el sistema pero en realidad está compitiendo con el resto por
obtener los recursos.
Debes diferenciar entre proceso y programa. Imagina que varios usuarios están visionando
documentos con un procesador de textos. Cada instancia del programa de procesador de
textos es un proceso separado. Nosotros distinguimos cada proceso por un número entero
positivo de identificación conocido como PID (Process Identifier). Si además un proceso ha
sido creado por otro decimos que este otro es “su padre” y podemos obtener su
identificador mediante el atributo PPID(Parent Process Identifier). De esta forma los
procesos pueden estar relacionados mediante una relación jerárquica de tipo árbol. De
hecho existe un primer proceso que inicia los demás llamado init que corresponde al
sistema operativo.
Además del PID y en caso de haberlo del PPID los procesos iniciados por un usuario
cuentan con un UID(User Identifier) y si éstos han sido ejecutados en un terminal de
comandos o consola cuentan con un valor de TTY (o bien aparecerá en esta columna un ?
indicando que no tiene terminal).
El comando ps acepta una cantidad elevada de opciones, cada una de ellas para mostrar
datos concretos. En general existen tres tipos de sintaxis para escribir estas opciones:
• Opciones GNU largas: comienzan por doble guión (--), son palabras y nunca las
agruparemos.
En cualquier caso siempre obtendremos una tabla cuyas columnas podrán tener los
siguientes rótulos:
Ejemplo 1: mostrar los procesos asociados a nuestra consola (que en este caso se
llamará terminal controlador).
Observa que en este ejemplo los procesos que aparecen son bash (es nuestra ventana de
terminal o consola), dos instancias del navegador web firefox y el propio comando ps. Para
cada proceso podemos observar su PID. También observa que todos los procesos se
ejecutan en el terminal pts/0. Antes de ver las opciones más utilizadas mostremos un poco
de ayuda con --help:
Ejemplo 2:mostrar todos los procesos del sistema (opción –e):
Ejemplo 3:mostrar todos los procesos (-e) con más columnas de información (opción –f):
Ejemplo 4: mostrar todos los procesos con más información extra (opción –F):
Ten en cuenta que la opción BSD u minúsculas (sin guión) es empleada para mostrar
información adicional (típicamente la columna USER). Es decir si hacemos ps U Javier
mostraremos los procesos del usuario Javier pero puede que no aparezca la columna
USER. Si quieres mostrar esta columna puedes hacer ps u U Javier.
Ejemplo 6:Mostremos todos los procesos (opción BSD a) sin terminal asociado (opción BSD
x):
Ejemplo 7:Y ahora todos los procesos (opción BSD a) sin terminal (opción BSD x) con la
columna usuario (opción BSD u, que sirve para mostrar la columna USER y otras
columnas):
Ejemplo 8: ¿Te interesa obtener una salida con una lista de columnas concreta? Puedes
utilizar –o indicando la lista de columnas separada por comas. En este ejemplo
obtendremos todos los procesos (-e) con las columnas (-o) usuario, pid y terminal:
Ejemplo 9: Sólo vamos a aclarar un aspecto. La opción -e muestra todos los procesos del
sistema como vimos en el ejemplo anterior. Sin embargo la opción -a muestra todos los
procesos pero de nuestra sesión (todas nuestras terminales).
Ejemplo 10: Para mostrar el árbol jerárquico de los procesos tenemos las opciones –H, -f y
--forest. Podríamos ejecutar ps –u Javier --forest. En muchos sistemas tenemos un
comando llamado pstreeque también muestra el árbol de relaciones. Típicamente con
pstree se usan las opciones –A y –G para obtener un árbol con líneas Ascii. La opción –u
mostrará además el usuario entre paréntesis. Ejemplo de uso: pstree –AGu.
Utizando ps es habitual emplear ps –eH. Prueba estas opciones en tu consola. Aquí te
mostramos un listado con las opciones –j (jobs o trabajos de los que hablaremos más
adelante) y --forest.
Por otra parte puede que necesites obtener los PID de los procesos creados por algún
comando concreto. Imagina que quieres obtener los procesos de todas las instancias de
bash. Utiliza una tubería (pipe) y el comando grep: ps ax | grep bash.
Por otra parte la opción –x mostrará procesos que no tienen un terminal controlador. Y la
opción –e mostrará información para todos (every) los procesos (similar a –a). Hay
opciones que incrementan la cantidad de información obtenida, como -f y -l
Para hacer el siguiente ejemplo hemos cambiado a un nuevo terminal, luego tendremos
(pts/0) y (pts/1). Será la opción -a la que nos permite ver los procesos de nuestra sesión,
aunque estén en terminales diferentes.
Como ves en el código anterior firefox se está ejecutando en pts/0 mientras que ps está en
pts/1.
Por último, la opción -o permite indicar exactamente las columnas que deseamos en el
listado. Por ejemplo, si quisiéramos obtener una lista de procesos que corresponden al
comando firefox con las columnas usuario,PID,terminal,tiempo de CPU y comando
haríamos:
El siguiente listado muestra todos los procesos de nuestra sesión (-a) utilizando el formato
de trabajos o jobs (-j). La salida está ordenada por la sesión (columna SID – session ID) en
orden descendente y por el nombre del comando en orden ascendente.
Ahora un listado similar al anterior pero queremos los dos órdenes ascendentes: dado que
este es el comportamiento por defecto no hará falta indicarlo.
Como siempre te recomendamos que consultes las páginas del comando man para ver
detalles particulares del comando ps, así como las opciones para especificar campos
concretos. También tendrás un resumen corto utilizando ps --help.
En relación a la carga media, si los procesos no demandan CPU la carga media será cero.
Si hay procesos haciendo uso intensivo de la CPU la carga media será uno. Si el valor es
mayor que uno significa que hay procesos compitiendo por el procesador. Si el valor fuera
muy elevado podría significar que hay algún proceso colgado, en ese caso utiliza top para
analizar la situación.
103.5.2.6. Comando top:
Los procesos son entidades dinámicas: cambian de estado, consumen recursos, crean
procesos hijo, mueren. Si ejecutamos varias veces el comando ps podríamos ir viendo los
cambios pero esto resulta engorroso. El comando top nos permite ver dinámicamente qué
está pasando con nuestros procesos. Lo que hace es mostrar una lista constantemente
actualizada de procesos con información útil de los mismos. El siguiente es un listado de
ejemplo de uso de top. Dado que es un comando dinámico será necesario detenerlo para
volver a la consola: teclea qpara finalizar.
El comando top, mientras está en ejecución, cuenta con un número de subcomandos. Los
más prácticos son los siguientes:
k nos permite matar un proceso (kill). Nos pedirá el PID del mismo.
s nos permite cambiar la velocidad (speed) de refresco de los datos. Nos pedirá el
nuevo valor en segundos. Por defecto top se actualiza cada 5 segundos.
p provoca que los datos se ordenen por el uso de CPU. Por defecto este el
comportamiento habitual de top.
m es similar a p pero provoca que los datos se ordenen por el uso de memoria.
o ordena el listado
Las opciones anteriores se utilizan una vez que estamos ejecutando top. Si directamente
quieres ejecutar este comando con alguna modificación tienes las opciones de comando.
Veamos algunas (no están todas):
top –p PID La opción –p es muy útil cuando quieres monitorizar sólo algunos procesos
específicos. Puedes usar esta opción hasta 20 veces. Ej: top –p 3812 –p 1529
top –u usuario La opción –u es muy útil cuando quieres monitorizar sólo los procesos
específicos de un usuario. Ej: top –u Gonzalo mostrará los procesos del usuario Gonzalo
top –n veces La opción –n indica que el comando se actualizará n veces y luego terminará
su ejecución.
top –b La opción –b sirve para especificar el modo por lotes, en el que top no emplea los
comandos normales de actualización de la pantalla. Se puede usar, por ejemplo, para
registrar en un fichero el uso de CPU de algún proceso.
La primera columna es el número de trabajo. En este ejemplo tenemos dos (el 1 y el 2). El
signo más junto al trabajo 2 indica que en este momento era el que estaba ejecutándose.
Hemos utilizado la opción –l para ver más información, concretamente la segunda columna
con los PID (lo que nos permitiría utilizar ps con estos procesos). A continuación hay una
columna con el estado (Running o Ejecutando en el ejemplo). Por último tenemos el
comando de cada proceso.
Este es uno de los usos de jobs: averiguar los PID de los procesos de nuestro terminal para
luego usarlos con ps o matar estos procesos. También hay muchas utilidades en Linux que
utilizan el número de tarea en lugar del PID, y jobs nos ayuda a obtenerlo. Por último jobs
tiene otra utilidad: si estamos trabajando con una sesión remota al cerrar la sesión
podemos dejar colgados procesos en el terminal remoto. Con jobs podemos comprobarlo y
cerrar estos procesos que han quedado sin control.
Para poder volver a tener la consola disponible para otros comandos nos haría falta
finalizar el proceso que está en foreground. También podemos pausarlo pulsando Control-
Z,pero el proceso quedaría suspendido sin realizar su tarea y volvemos a tener el terminal
operativo. Probémoslo:
Ejecuta top en un terminal. Se está ejecutando en primer plano, con lo que el terminal
queda inutilizado, no puedes escribir otros comandos. Podríamos terminar top (recuerda
que para eso basta con escribir q), pero no queremos finalizar el proceso sino utilizar el
terminal para otros comandos. Entonces pausaremos top escribiendo: Control-Z. Aparecerá
un mensaje indicando que top ha sido detenido (estado Stopped) y tiene un número de
tarea 1. La consola está disponible (y top pausado). Escribe el comando ls para listar el
contenido de tu carpeta. A continuación escribe el comando fg que volverá a traer el
proceso top a primer plano. Termina esta prueba saliendo de top con la opción q.
¿Entonces ocurre que en un terminal sólo podremos ejecutar un proceso cada vez, o bien
tendremos que pausarlo con Ctrl-Z para ejecutar otro? La respuesta es no. Existe la
ejecución de procesos en segundo plano (background). Los procesos que estén en
segundo plano se estarán ejecutando con el resto de procesos del sistema, y estarán
realizando su tarea sin que nosotros aparentemente lo advirtamos (a menos, claro, que
requieran una entrada de datos), dejando el terminal libre para otras actividades. Colocar
un proceso en segundo plano es útil si se trata de procesos que hacen uso intensivo de la
CPU y requieren muy poca información de entrada.
Este pequeño código hace un bucle infinito que consiste en dormir durante 5 segundos y
después imprimir la fecha actual. Éste es ahora nuestro segundo trabajo [2] con PID 3065.
Se está ejecutando en background e imprime cada 5 segundos la fecha y hora. Para
pausarlo debemos hacer lo siguiente:
RECUERDA: para pausar un proceso con Ctrl-z éste debe estar en primer plano.
Si ejecutas jobs verás que el primer trabajo está en ejecución y el segundo está detenido.
Eso sí, el segundo trabajo ya no está en background (observa que en la descripción del
comando ha desaparecido la & final). Esto es porque el comando fg trajo el trabajo 2 al
primer plano. Para terminar esta prueba mataremos el trabajo 2 con kill %2. Hacemos jobs
y quedará un único trabajo en background.
Continuando con nuestro ejemplo anterior tenemos un único trabajo, el comando yes, en
background.
Con firefox & se crea un segundo trabajo (el navegador firefox) que está en ejecución en el
background. Se abrirá la ventana del navegador (minimízala) y el terminal estará
operativo:
El comando fg (foreground) permite transferir un proceso al primer plano. Recuerda
pausarlo con Ctrl-Z. Observa el ejemplo:
Ahora ejecutamos jobs para ver el estado de nuestros trabajos. Recuerda el símbolo [+]
que indica que está al frente (primer plano) o es el proceso actual. Observa también que
ha desaparecido el & en el proceso de firefox.
Si utilizamos fg sin ningún número de tarea traeremos al frente la tarea más reciente.
También podríamos traer el frente un proceso sin conocer su número de tarea, utilizando el
nombre del comando. Por ejemplo:
fg %firefox traerá al frente todos los procesos que sean navegadores firefox.
fg %fir Traerá al frente todos los procesos que empiecen por fir.
El comando bg tiene la misma sintaxis que el comando fg. Los comandos fg, bg y jobs
son internos a la Shell o terminal donde se utilizan. Por este motivo utilizan los números de
tarea y no los PID.
Para terminar nuestro ejemplo mataremos los trabajos 1 y 2 con kill %1 y kill %2 .
Utilizando bg sin parámetros enviamos el proceso que esté al frente en ese momento al
segundo plano.
Ambos comandos, bg y fg, permiten indicarle un número de trabajo, que podemos obtener
con jobs.
Si en un momento dado necesitas saber el PID de un trabajo de nuestra sesión utiliza jobs
–l.
Al utilizar jobs el proceso que en ese momento es el trabajo actual ejecutado en el
terminal vendrá marcado con un signo +.
Los tres comandos fg, bg y jobs operan con los procesos del terminal, que se llaman
trabajos o tareas.
A menos que se usen los mecanismos de redirección, la salida estándar (stdout) y la salida
estándar de errores (stderr) serán redirigidos hacia el terminal controlador.
En este caso la Shell Bash suspende el proceso, de forma que no se ejecutará más tiempo.
Es decir: si un proceso en background necesita información de entrada
automáticamente se pausará.
Lo que tendremos que hacer sería traer el proceso al primer plano con fg, aportarle la
entrada necesaria y volverlo a llevar al background con bg.
El siguiente código ilustra un ejemplo sencillo. Se trata de un pequeño script que imprime
la fecha, después redirige lo que escribamos hacia un fichero llamado entradas.dat, y por
último vuelve a imprimir la fecha. El segundo paso, que utiliza el comando cat, requiere
entrada por parte del usuario. Lanzamos el script en background:
Debes tener en cuenta que en algunas shell es necesario pulsar Enter en el terminal para
ver el estado de los procesos en Background. En esta distribución de Fedora Linux hemos
tenido que hacerlo. En ese momento observamos cómo nuestro script está detenido.Se
imprimió la primera fecha y se detuvo el proceso pues el comando cat requiere entrada
por teclado.
Para finalizar el script lo traemos al primer plano (con fg) y escribiremos unas líneas de
texto seguida de Ctrl-D para señalar el final de la entrada.
Ahora el proceso ha finalizado su ejecución imprimiendo la última fecha. Si quisiéramos
podríamos abrir el fichero creado entradas.dat.
El sistema operativo se comunica con los procesos mediante el envío de señales. En este
caso al cerrar el terminal es muy probable que la Shell envíe a sus procesos hijo la señal
SIGHUP (que significa “colgar”) y los cierre.
Hagamos una pequeña prueba: En un terminal nuevo ejecuta firefox &. Se abre la ventana
del navegador y se ejecuta firefox en segundo plano. Vuelve a la consola. Vamos a ver
nuestros procesos (comando ps) con su relación jerárquica (opción --forest), en un listado
donde aparezcan sólo las columnas PID, PPID, CMD (opción –o pid,ppid,cmd):
Aquí observamos que nuestro terminal (que es el comando bash con PID 1450) es el
proceso padre (PPID) para otros dos procesos: el firefox y el propio comando ps que hemos
ejecutado. Si ahora cierras el terminal observarás que se cierra también la ventana de
firefox.
Repitamos el proceso pero usando nohup. Abrimos un terminal nuevo pero en este caso
ejecutamos: nohup firefox &
También se ha lanzado el proceso firefox en segundo plano y el terminal ha mostrado un
mensaje que dice “nohup: se descarta la entrada y se añade la salida a nohup.out”. En un
momento hablaremos de este mensaje.Prueba ahora a cerrar el terminal. Observarás que
firefox permanece en ejecución.
El comando nohup hace una tarea más. De forma automática redirige las salidas estándar
stdout y stderr del proceso a un fichero llamado nohup.out o bien $HOME/nohup.out. En
el caso de que se detecte que no se puede escribir en este fichero entonces nohup no se
ejecutará.
Si queremos escribir en otro fichero que no sea nohup.out tendremos que redirigir stdout
y/o stderr hacia el fichero deseado.
En el siguiente código haremos esto mismo con un pequeño script que guardaremos en el
fichero micomando.dat. Lo que hace el script es escribir por pantalla la hora cada 15
segundos.
Tras unos minutos mata el trabajo 1 con kill %1 y muestra el contenido del fichero
nohup.out (utilizando cat nohup.out). Observarás que fue ahí donde se grabó las fechas
puesto que nohup redirigió la salida hacia ese fichero:
Pruébalo y no olvides matar el trabajo 1 con kill %1, para evitar que se esté escribiendo en
el fichero nohup.out eternamente. Recuerda, por último, que si quieres que nohup escriba
en otro fichero debes redirigir su salida.
El ejemplo más evidente acabamos de estudiarlo. Al cerrar un terminal éste proceso envía
a todos sus procesos hijo la señal SIGHUP (“colgar”). También hemos empleado
intuitivamente otra señal: cuando teníamos un proceso en primer plano y queríamos
pausarlo escribíamos Ctrl-Z. Esto envía al proceso la señal SIGTSTP (“stop o detener”).
Observa que cada señal tiene un número o identificador asociado. Podríamos usar
la opción –s seguida del nombre de la señal, o bien la opción –n seguida del número, o
incluso –nombre_señal. Las siguientes tres líneas son equivalentes (en todas estamos
enviando la señal SIGHUP al trabajo con id de tarea 6:
kill –SIGTSTP 5847 mandará la señal de Stop al proceso con PID 5847.
Después ejecutamos kill –SIGTSTP 4287. Hemos enviado la señal de Stop al proceso. Aquí
nos damos cuenta de que kill no muestra ningún mensaje por pantalla. Para comprobarlo
utilizamos jobs y vemos que el proceso está detenido y ha desaparecido la & final. La
señal SIGTSTP equivale a traer el proceso al frente (como el comando fg) y detenerlo (con
Ctrl-Z).
Por último enviamos al mismo proceso la señal SIGCONT (“continuar”), que ha colocado de
nuevo el proceso en background en ejecución (luego es equivalente a utilizar el comando
bg).
Ten en cuenta que el comando kill te permitirá enviar señales a tus procesos, pero
raramente podrás enviar señales a procesos de otros usuarios, a menos, claro, que seas el
usuario root.
Por último también se soporta omitir la palabra SIG cuando usamos la opción –
nombre_señal. Las dos líneas siguientes son equivalentes:
killall firefox
Y se enviaría a todos la señal SIGTERM (15), ya que este comando funciona igual que kill.
killall –HUP firefox enviará la señal SIGHUP a todos los procesos de firefox.
-i antes de enviar la señal a cada proceso nos pedirá una confirmación de tipo (y/n), de
forma que para cada proceso decidamos si enviar o no la señal. Esta opción es obligatoria
si estamos utilizando el usuario root ya que podríamos destruir procesos de algunos
usuarios de nuestro sistema.