.. _procesos: Control de procesos =================== *linux* es un sistema operativo multitarea, esto es, capaz de ejecutar varios programas en paralelo. Al hilo de este asunto, cabe hacer una serie de definiciones: **Proceso** Se denomina proceso, simplemente, a un programa que está en ejecución. Cada procesos tiene una serie de propiedades que definen su estado. Una de ellas, muy importante es el |PID|. .. _pid: **PID** (Process IDentifier) Es el número asociada a un proceso que lo identifica de manera inequívoca. Esto implica que es único. **Demonio** (**servicio** en la terminología de los sistemas *windows*) Es un proceso que se ejecuta en segundo plano, es decir, que se ejecuta sin que intervenga en su ejecución de manera interactiva el usuario. **Prioridad** Es la preferencia que el sistema le da a la ejecución de un proceso. Está representada por un número entre *-20* (máxima prioridad) y *19* (mínima prioridad). La prioridad normal es *0*. Bajo este epígrafe trataremos el modo de conocer cuáles son los procesos que ejecuta el sistema, qué recursos consumen, cómo cancelarlos o como traerlos a primer plano y mandarlos a segundo plano. La gestión de los demonios, por ser más un asunto de servidor, se dejará para más adelante. .. _consproc: Consulta -------- .. _ps: .. index:: ps :manpage:`ps` Permite obtener información sobre los procesos que se ejecutan en el sistema. Hay dos modos de pasarle opciones: siguiendo el estilo *BSD*, en que las opciones no van precedidas de guión; y siguiendo el estilo *unix*, en que son precedidas por uno. Por coherencia con el resto de comandos, usaremos este segundo método\ [#]_. El modo más elemental de uso es aquel que muestra todos los procesos:: $ ps -e PID TTY TIME CMD [...] 518 ? 00:00:00 ntpd 520 ? 00:00:00 samba 522 ? 00:00:00 samba 523 ? 00:00:00 samba 524 ? 00:00:00 samba 525 ? 00:00:00 samba 526 ? 00:00:00 smbd 527 ? 00:00:00 samba 528 ? 00:00:00 samba 529 ? 00:00:00 samba 530 ? 00:00:00 samba 531 ? 00:00:00 samba 532 ? 00:00:00 winbindd 533 ? 00:00:00 samba 534 ? 00:00:00 samba 535 ? 00:00:00 samba 536 ? 00:00:00 samba 541 ? 00:00:00 smbd-notifyd 542 ? 00:00:00 cleanupd 544 ? 00:00:00 winbindd 545 ? 00:00:00 lpqd [...] o bien todos los procesos que están asociados a una terminal:: $ ps -a PID TTY TIME CMD 3068 pts/1 00:00:06 vim 3913 pts/0 00:00:00 tmux: client 4354 pts/5 00:00:00 su 4368 pts/5 00:00:00 bash 5490 pts/4 00:00:00 vim 5654 pts/7 00:00:00 su 5667 pts/7 00:00:00 bash 5672 pts/3 00:00:00 ps En la salida se observan entre otros el |PID| del proceso, la terminal asociada y el ejecutable que lo originó. Puede obtenerse un formato largo que da más información con ``-f``:: $ ps -ef [...] ntp 518 1 0 11:08 ? 00:00:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:111 root 520 1 0 11:08 ? 00:00:00 /usr/sbin/samba root 522 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 523 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 524 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 525 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 526 522 0 11:08 ? 00:00:00 /usr/sbin/smbd -D --option=server role check:inhibit=yes --foreground root 527 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 528 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 529 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 530 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 531 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 532 531 0 11:08 ? 00:00:00 /usr/sbin/winbindd -D --option=server role check:inhibit=yes --foreground root 533 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 534 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 535 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 536 520 0 11:08 ? 00:00:00 /usr/sbin/samba root 541 526 0 11:08 ? 00:00:00 /usr/sbin/smbd -D --option=server role check:inhibit=yes --foreground root 542 526 0 11:08 ? 00:00:00 /usr/sbin/smbd -D --option=server role check:inhibit=yes --foreground root 544 532 0 11:08 ? 00:00:00 /usr/sbin/winbindd -D --option=server role check:inhibit=yes --foreground root 545 526 0 11:08 ? 00:00:00 /usr/sbin/smbd -D --option=server role check:inhibit=yes --foreground [...] Los procesos derivan unos de otros, de manera que un proceso tiene un proceso padre. SI se quiere observar esta jerarquía de permisos puede usarse la opción ``-H``:: $ ps -eH [...] 518 ? 00:00:00 ntpd 520 ? 00:00:00 samba 522 ? 00:00:00 samba 526 ? 00:00:00 smbd 541 ? 00:00:00 smbd-notifyd 542 ? 00:00:00 cleanupd 545 ? 00:00:00 lpqd 523 ? 00:00:00 samba 524 ? 00:00:00 samba 525 ? 00:00:00 samba 527 ? 00:00:00 samba 528 ? 00:00:00 samba 529 ? 00:00:00 samba 530 ? 00:00:00 samba 531 ? 00:00:00 samba 532 ? 00:00:00 winbindd 544 ? 00:00:00 winbindd 533 ? 00:00:00 samba 534 ? 00:00:00 samba 535 ? 00:00:00 samba 536 ? 00:00:00 samba [...] Alternativa a la opción ``-H`` es ``--forest``, con la que obtenemos una salida más vistosa y elocuente:: $ ps -e --forest [...] 518 ? 00:00:00 ntpd 520 ? 00:00:00 samba 522 ? 00:00:00 \_ samba 526 ? 00:00:00 | \_ smbd 541 ? 00:00:00 | \_ smbd-notifyd 542 ? 00:00:00 | \_ cleanupd 545 ? 00:00:00 | \_ lpqd 523 ? 00:00:00 \_ samba 524 ? 00:00:00 \_ samba 525 ? 00:00:00 \_ samba 527 ? 00:00:00 \_ samba 528 ? 00:00:00 \_ samba 529 ? 00:00:00 \_ samba 530 ? 00:00:00 \_ samba 531 ? 00:00:00 \_ samba 532 ? 00:00:00 | \_ winbindd 544 ? 00:00:00 | \_ winbindd 533 ? 00:00:00 \_ samba 534 ? 00:00:00 \_ samba 535 ? 00:00:00 \_ samba 536 ? 00:00:00 \_ samba [...] También hay formas de filtrar los procesos mostrados según distintos criterios. Por ejemplo, para elegir los de un determinado usuario:: $ ps -u josem o elegir procesos por nombre:: $ ps -C systemd o por |PID|\ [#]_:: $ ps 1000 o mostrar los procesos de un determinado padre. Para ello se debe indicar el |PID| del proceso padre:: $ ps --ppid 1579 :command:`ps` permite incluir varias opciones de filtrado:: $ ps -C bash -u josem incluso varias veces la misma opción:: $ ps -C bash -C system pero nunca acomulan el efecto de filtrado, sino el resultado. Es decir, en el ejemplo:: $ ps -C bash -u josem no devuelve los procesos de :program:`bash` que esté ejecutando el usuario "josem", sino cualquier proceso de :program:`bash` (sea o no de "josem") más cualquier proceso que pertenezca a "josem" (sea de :program:`bash` o de cualquier otro programa). En el segundo ejemplo:: $ ps -C bash -C system la orden devuelve cualquier proceso de :program:`bash` o de :ref:`systemd `. Cuando el criterio es el mismo también se puede usar esta alternativa:: $ ps -C systemd,bash .. warning:: Tenga presente que si quiere que los criterios de filtrado sean acomulativos, esto es, que el resultado cumpla ambos criterios, tendrá que recurrir a :ref:`pgrep `. También se puede definir exactamente qué campos se quieren obtener mediante la opción ``-o`` seguida de los nombres de los campos (véase la página del manual). Por ejemplo, esto mostraría para todos de los procesos el nombre del usuario que lo ejecuta, el *pid*, el *ppid* y el ejecutable:: $ ps -eo user=,pid=,ppid=,comm= El signo *igual*, indica que no se desea que :command:`ps` incluya para el campo cabecera. Si todos los campos incluyen un igual, entonces no habrá cabecera alguna. Se pueden también ordenar los resultados con ``-sort``:: $ ps -eo user=,pid=,ppid=,comm= --sort ppid,pid .. _pstree: .. index:: pstree :manpage:`pstree` Muestra los procesos del sistema en forma de árbol, tal como hace el comando :ref:`tree ` con los directorios y ficheros. Para constituir este árbol debe saber que todo proceso tiene un proceso padre del que deriva. Por ejemplo, si en una sesión de :program:`bash` ejecutamos este comando :command:`pstree`, el proceso correspondiente a éste es hijo del proceso de :command:`bash`. .. _pgrep: .. index:: pgrep :manpage:`pgrep` Permite obtener el |PID| de un proceso atendiendo a distintos criterios. Su uso más sencillo es obtener los |PID| asociado al nombre de un programa. Por ejemplo, esto devolvería todos los procesos que se corresponden con sesiones de :program:`bash`:: $ pgrep bash 2966 3004 3084 3588 3811 3967 4368 4546 5529 Puede no indicarse el nombre del programa, en cuyo caso se entenderá que deseamos el de cualquier programa, o bien, utilizar una :ref:`expresión regular ` que nos permitirá hacer búsquedas más poderosas. Por ejemplo, esta búsqueda:: $ pgrep 'sh$' nos devolverá los |PID| de todos los procesos cuyo nombre de programa acabe en "sh". .. warning:: En realidad el argumento de :command:`pgrep` es simplemente un patrón expresado en forma de :ref:`expresión regular extendida `, incluso en el primer ejemplo:: $ pgrep bash Por tanto, este primer ejemplo no devuelve los |PID| de los procesos de :program:`bash`, sino los |PID| de cualquier programa que dentro de su nombre incluya la cadena "bash". En principio, la concordancia se realiza únicamente con el nombre del proceso, pero puede buscarse concordancia con la orden completa (que incluye parámetros) utilizando la opción :kbd:`-f`. Por ejemplo:: $ pgrep -f 'systemd.*user' 937523 concordaría con procesos de :program:`systemd` propios de usuarios:: $ pgrep -af 'systemd.*user' 937523 /lib/systemd/systemd --user Para filtrar los resultados podemos añadir opciones que fija criterios adicionales. Por ejemplo:: $ pgrep -u usuario 1223 1300 1311 1328 1380 1387 permite obtener los |PID| de todos los procesos (no hemos indicado qué programa) que pertenezcan al usuario de nombre "usuario". O bien:: $ pgrep -P 1114 1116 2602 devuelve los procesos cuyo proceso padre es el proceso 1114. A diferencia de :ref:`ps ` los criterios de filtro son acumulativos, por lo que si se utilizan varios, :command:`pgrep` sólo devolverá aquellos que cumplan con todos. En consecuencia:: $ pgrep -u usuario bash devolverá los procesos de :program:`bash` a nombre del usuario "usuario". Además, debe tenerse en cuenta que en las opciones (pero no en el patrón que debe ser único), pueden indicarse varios criterios a la vez:: $ pgrep -u usuario,root bash que devolverá los procesos de :program:`bash` a nombre de "usuario" o "root". Otra opción interesante es :kbd:`-c` que en vez de devolver los |PID| de los procesos, devuelve cuántos procesos en total. Por tanto, pasa saber cuántos procesos está ejecutando el usuario "usuario":: $ pgrep -cu usuario 6 Lamentablemente, :command:`pgrep` sólo devuelve el |PID| (y la orden completa con :kbd:`-a`) y no una información tan completa y configurable como :ref:`ps `.\ [#]_ .. _top: .. index:: top :manpage:`top` Permite observar los procesos en tiempo real:: $ top .. _htop: .. index:: htop :manpage:`htop` Es una aplicación que mejora la interfaz de :ref:`top `:: $ htop Es probable que no esté incluida en la instalación base y requiera su instalación explícita. .. _uptime: .. index:: uptime :manpage:`uptime` Muestra el tiempo trascurrido desde el arranque. el número de usuarios conectados y la carga media del sistema en el último minuto, los cinco últimos minutos y los quince últimos minutos:: $ uptime 00:07:44 up 116 days, 12:15, 2 users, load average: 0,00, 0,03, 0,09 Tiene algunas opciones. Con ``-s`` da una respuesta muy parecida a :ref:`who ` con la opción ``-b``:: $ uptime -s 2016-09-09 12:52:12 .. _time: .. index:: time :manpage:`time` Permite conocer el tiempo que tarda una orden en completarse:: $ time sleep 2 real 0m2.009s user 0m0.004s sys 0m0.000s **real** es el tiempo trascurrido desde que comenzó la orden hasta que se completo. **user** el tiempo de |CPU| fuera del *kernel* empleado y **sys** el tiempo de |CPU| dentro del **kernel** empleado. Por tanto, la suma de las dos últimas cantidad indica el tiempo total de |CPU| empleada. Manipulación ------------ Ya se ha explicado :ref:`cómo dar órdenes `. Una orden provoca la creación de un proceso durante un determiando tiempo. Ahora bien, es posible modificar la forma en que se da la orden para lograr distintos fines. .. _nice: .. index:: nice :manpage:`nice` Modifica la prioridad de un proceso. Cuando se ejecuta una orden, la prioridad del proceso es *0*. Sin embargo, :command:`nice` permite cambiar esta prioridad. Para usuarios distintos del administrador sólo se puede disminuir la prioridad, es decir, dar valores positivos. Para usar :command:`nice` basta con anteponerlo al proceso que se quiere ejecutar. Por ejemplo:: $ nice ffmpeg -i input.wmv -s hd720 -c:v libx264 -crf 23 -c:a aac -strict -2 output.mp4 recodifica una película en calidad HD720, haciendo que para este proceso bastante costoso disminuya la prioridad. Cuando :command:`nice` se usa sin indicar la prioridad, se supone que esta es *10*. Puede especificarse la prioridad exacta con la opción ``-n``:: $ nice -n10 ffmpeg [...] Valores negativos hace el proceso más prioritario de lo normal, pero deben adjudicarse como *root*. .. _renice: .. index:: renice :manpage:`renice` Modifica la prioridad de un proceso ya comenzado. Para seleccionar este proceso necesitamos el *pid* del mismo, el cual podemos obtener a traves de :command:`ps`, por ejemplo. Suponiendo que sea el *5789*:: $ renice -n 10 -p 5789 .. _kill: .. index:: kill :manpage:`kill` Envía señales a los procesos, muy comúnmente para acabar con ellos, de ahí su nombre. Hay una larga lista de señales que pueden obtenerse mediante la opción :kbd:`-L`:: $ kill -L 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX Las más usadas para acabar procesos son: **SIGTERM** (15) Que le indica al proceso que haga un apagado suave e intente cerrar antes todo los recursos que tenga abiertos. Es el apagado más recomentable, aunque no siempre funciona, sobre todo si el proceso tiene algún hijo. Es el apagado que :command:`kill`, :ref:`pkill ` o :ref:`killall ` intentan por defecto si no se especifica otro concreto. **SIGHUP** (1) *HUP* proviene de *hang up*, esto es, colgar y es la señal que recibían los programas cuando en accesos remotos por conexión serie el usuario decide colgar. En sistemas modernos este acceso no es tan común y la señal se ha reciclado y significa que la terminal dentro de la que corre el programa se ha cerrado. En bastantes programas interactivos la señal puede tener el efecto de un apagado suave como *SIGTERM*, pero en los demonios, que como no son interactivos, no suelen ejecutarse en una terminal, es común que se interprete como que es necesario volver a leer la configuración y, en consecuencia, el programa no acabe. Por tanto, si nuestra intención es acabar un proceso de forma suave, es más recomendable la opción anterior. **SIGINT** (2) Acaba taxativamente el proceso, aunque éste puede no hacer caso a la señal. Equivale a :kbd:`Ctrl+C` sobre un proceso en primer plano. **SIGKILL** (9) Provoca el apagado obligatorio, por lo que, aunque tiene las mismas consecuencias de la señal anterior (puede quedar algo abierto), la señal no puede ser obviada por el proceso. Lo habitual, cuando se intenta acabar manualmente con un proceso, es intentar el apagado suave (*SIGTERM*) y, si este no es posible, intentar el apagado forzoso (*SIGKILL*). Por tanto, si quisiéramos acabar con los procesos de |PID| 1037 y 1000, haríamos:: $ kill 1897 1000 o bien:: $ kill -15 1897 1000 que es lo mismo. Y, si esto no funciona, no tendremos más remedio que hacer:: $ kill -9 5675 6676 .. note:: En ocasiones, es imposible acabar del todo con un proceso ni aun con la señal ``SIGKILL`` (*9*). En estos casos, el proceso acaba en un estado *zombi* por tiempo indefinido, que se nota con un **Z**\ al consultar el proceso con :command:`ps`. **SIGTSTP** (20) Suspende el proceso, esto es, lo deja en :ref:`estado "Suspendido" ` a la espera de que otra orden de usuario vuelva a ponerlo en ejecución. Equivale a :kbd:`Ctrl+Z` sobre un proceso en primer plano. **SIGSTOP** (19) Como el anterior, pero la parada es más agresiva. Es preferible la orden anterior. **SIGCONT** (18) Reanima un proceso suspendido. El uso de :command:`kill` es bastante sencillo:: $ kill -SEÑAL PID1 PID2 ... o sea, se indica la señal y se indican la relación de |PID| correspondientes a los procesos a los que se quiere enviar la señal. Para expresar la señal podemos usar el número (p.e. **9**), su nombre (p.e. *SIGKILL*) o su nombre abreviado (p.e. *KILL*). .. warning:: :command:`kill` es una orden interna del intérprete, por lo que depende de este. Usar el nombre completo (*SIGKILL*) funciona en la versión de :command:`bash`, pero no en :command:`dash` También es posible utilizar en vez del |PID| del proceso, su identificador de trabajo en la sesión (véase :ref:`jobs `), pero antecediéndolo con un "%":: $ sleep 1000 & [1] 12699 $ jobs [1]+ Ejecutando sleep 1000 & $ kill -TSTP 12699 $ jobs [1]+ Detenido sleep 1000 $ kill -CONT %1 $ jobs [1]+ Ejecutando sleep 1000 & .. _pkill: .. index:: pkill :manpage:`pkill` Es una orden que, como :ref:`kill `, permite enviar señales a los procesos, pero para cuya selección se usa la sintaxis de :ref:`pgrep `. Por tanto, podremos referirlos mediante su nombre (no su |PID|) añadiendo criterios acomulativos de selección como con :command:`pgrep`, y además, indicar qué señal enviar como con :command:`kill`:: # pkill -15 -uroot bash .. _killall: .. index:: killall :manpage:`killall` Cancela procesos identificándolos por su nombre. Pueden usarse las señales indicadas anteriormente. Por ejemplo, esto cancela de forma suave todas las sesiones de :program:`bash` abiertas que pueda cancelar quien lo ejecuta:: $ killall bash Tiene opciones (:kbd:`-u`, :kbd:`-g`, etc.) para ser más específico, pero no dispone de tantas como :command:`pkill`. .. warning:: killall es parte del paquete :deb:`psmisc`, que puede no encontrarse instalado por defecto. Por lo general, cuando se ejecuta una orden, la *shell* espera hasta que esta haya acabado para liberar la línea de comandos. Esto es debido a que la orden se ejecuta en primer plano. Arrancada de este modo, podemos escribir :kbd:`Ctrl+C` para cancelar la orden tal como haríamos con :command:`kill`; pero también podemos escribir :kbd:`Ctrl+Z` para detener la orden. Si hacemos esto segundo, la orden deja de ejecutarse, pero no están cancelada: simplemente queda a la espera de que demos la orden de proseguir. Por ejemplo, supongamos que hacemos una cuenta de 1 a 10 esperando un segundo entre número y número:: $ (for i in {1..10}; do sleep 1; echo $i; done) 1 ^Z [1]+ Detenido ( for i in {1..10}; .. _jobs: .. index:: jobs :command:`jobs` (orden interna de la *shell*) Permite consultar la lista de trabajos activos en la sesión actual:: $ jobs [1]+ Detenido ( for i in {1..10}; Por tanto, hay una tarea detenida. Si deseamos que prosiga, hay dos posibilidades: que mandemos que se ejecute en primer plano... .. _fg: .. index:: fg :command:`fg` (orden interna de la *shell*) Manda una tarea a primer plano (y la activa en caso de que estuviera suspendida). Para referirse a ella se debe especificar el número de trabajo que proporciona :command:`jobs`:: $ fg %1 2 3 ... 10 $ .. note:: Para refefir el proceso por su |PID| en vez de por su número de trabajo debe antecederse el número con :kbd:`#` en vez de con :kbd:`%`. o mandamos que se ejecute en segundo plano... .. _bg: .. index:: bg :command:`bg` (orden interna de la *shell*) Manda una tarea a segundo plano. Para referirse a ella se debe especificar el número de trabajo que proporciona :command:`jobs`:: $ bg %1 Es posible también ejecutar una tarea en segundo plano acabando la orden con un *&*:: $ sleep 60 & [1] 15991 $ jobs [1]+ Ejecutando sleep 60 & .. _ej-procesos: .. include:: /99.ejercicios/081-procesos.rst .. rubric:: Notas al pie .. [#] Aunque lo habitual es verlo explicado al estilo BSD: =========== ======================== BSD UNIX =========== ======================== :code:`ax` :code:`-ef` :code:`axf` :code:`-ef --forest` =========== ======================== .. [#] Para utilizar el criterio del |PID| pueden utilizarse la opción :kbd:`-p`:: $ ps -p 1000 .. [#] Como :ref:`ps ` da más posibilidades de formateo, es muy útil aunar ambos comandos. Por ejemplo:: $ ps -f $(pgrep -u usuario bash) en donde hemos usado :command:`pgrep` para obtener la lista de |PID| de los procesos que nos interesan.