LinuxPedia

Wiki libre et indépendant dédié à GNU-Linux et BSD.

Outils pour utilisateurs

Outils du site


commande:job_control

Contrôle des processus

Dans un terminal, il est possible d'interagir avec le noyau ou les processus en action. Il suffit de quelques commandes pour maîtriser la gestion des tâches.

Les commandes qui nous intéressent sont ps, top, kill, killall, bg, fg.

<note>Un signe $ précède les commandes qui ne nécessitent pas des droits administrateurs, un signe # celles qui nécessitent des droits administrateurs (ces signes ne font PAS partie des commandes). Les lignes qui ne commencent pas par un signe $ ou # correspondent au résultat de la commande précédente.</note>

La commande ps

La commande ps permet de voir l'état des processus en cours d'exécution sur une machine. C'est une photographie de ce qui est en train de tourner sur un système.
Lancée en simple utilisateur ou en root, elle permettra de voir de nombreuses informations sur les processus. ps est rarement utilisée sans option, on utilisera rapidement des options pour avoir toutes les informations nécessaires.
Par exemple :

$ ps aux

On obtient donc :

  • L'utilisateur,
  • le PID de chaque processus: c'est son numéro d'identification,
  • l'utilisation du processeur, de la mémoire vive, la date d'exécution, le temps d'exécution,
  • le nom de chaque processus lancé.

On pourra également obtenir une représentation des filiations entre processus en ajoutant l'option “--forest”, ou représentation en arborescence:

$ ps aux --forest
"pstree" pour lister les relations entre processus

Pour obtenir une représentation graphique des relations de filiation entre processus vous pouvez utiliser la commande “pstree”. L'option “-p” permet d'afficher également le pid des processus qui est normalement masqué:

$ pstree -p

Les pid des processus sont listés entre parenthèses “()”, les processus fils de même nom que le processus parent entre accolades “{}”. Lorsque plusieurs occurrences d'un processus sont présentes, elles sont groupées, placées entre crochets “[]” (et accolades s'il s'agit d'un processus fils), et le nombre d'occurrences est indiqué avec une étoile “*”. Par exemple 4*[{cupsd]} pour 4 occurrences du processus fils “cupsd”.

(la capture ne montre pas les pid)

Trier la sortie de "ps"

Pour cibler un processus particuliers dans la sortie de “ps”, il est facile d'utiliser “grep” en redirigeant le résultat de “ps”:

$ ps auxf | grep hald
106       6381  0.0  0.1  36892  5412 ?        Ss   07:19   0:00 /usr/sbin/hald
root      6384  0.0  0.0  15800  1232 ?        S    07:19   0:00  \_ hald-runner
root      6419  0.0  0.0  28320  2044 ?        S    07:19   0:00      \_ hald-addon-input: Listening on /dev/input/event5 /dev/input/event3 /dev/input/event2 /dev/input/event0
root      6468  0.0  0.0  28320  2056 ?        S    07:19   0:01      \_ hald-addon-storage: polling /dev/sr0 (every 2 sec)
root      6480  0.0  0.0  28328  2000 ?        S    07:19   0:00      \_ /usr/lib/hal/hald-addon-cpufreq
1000     26088  0.0  0.0   9340   868 pts/2    S+   16:06   0:00      \_ grep hald

On constate qu'à la dernière ligne le processus de recherche avec “grep” est lui-même listé. Pour éviter ceci il suffit d'utiliser comme motif de recherche une expression rationnelle:

$ ps auxf | grep -e [h]ald
106       6381  0.0  0.1  36892  5412 ?        Ss   07:19   0:00 /usr/sbin/hald
root      6384  0.0  0.0  15800  1232 ?        S    07:19   0:00  \_ hald-runner
root      6419  0.0  0.0  28320  2044 ?        S    07:19   0:00      \_ hald-addon-input: Listening on /dev/input/event5 /dev/input/event3 /dev/input/event2 /dev/input/event0
root      6468  0.0  0.0  28320  2056 ?        S    07:19   0:01      \_ hald-addon-storage: polling /dev/sr0 (every 2 sec)
root      6480  0.0  0.0  28328  2000 ?        S    07:19   0:00      \_ /usr/lib/hal/hald-addon-cpufreq

Cette fois “grep “n'apparaît plus. Pour plus de détails voir "grep" et "egrep".

On peut également utiliser directement “pgrep” pour faire une recherche rapide, et “pkill” pour terminer des processus:

$ pgrep -l hald
6371 hald
6374 hald-runner
6409 hald-addon-inpu
6450 hald-addon-cpuf
6451 hald-addon-acpi
6459 hald-addon-stor

L'option “-l” liste le nom des processus en plus de leurs pid. On peut également utiliser l'option “-u” pour cibler les processus appartenant à un utilisateur particulier:

$ pgrep -u root -l hald

pkill” permet d'envoyer un signal (défaut “SIGTERM”) à un ou plusieurs processus, en fonction de leurs noms ou de leurs pid:

$ pkill -u tux konqueror

Ici on termine le(s) processus “konqueror” appartenant à l'utilisateur “tux”.

La commande top

Il existe une commande qui permet d'avoir les mêmes informations que ps, mais cette fois-ci en temps réel. Vous l'aurez deviné, c'est la commande top.
Attention, la commande est très complexe, il faut lancer …. ! :

$ top

Par défaut, l'affichage se rafraîchit toutes les 3 secondes. Pour changer cela, il suffit d'utiliser l'option “delay” avec le temps en secondes, par exemple pour obtenir respectivement un rafraîchissement de 10 et 0.5 (1/2) secondes :

$ top -d 10
$ top -d 0.5

Vous verrez alors que les informations sont plus importantes. On obtient, en plus de ps aux, l'utilisation de la swap, la charge du processeur, le nombre de processus…etc.
Par ailleurs, cette fois-ci, les processus sont classés du plus gourmand en processeur au moins gourmand.

Quelques options sympathiques tout de même :

  • top -u utilisateur : permet de n'avoir que les processus de “utilisateur”
  • top -p1234 : permet de n'avoir que le processus qui a le PID 1234

“top” est un programme interactif, il accepte de nombreuse options et commandes, si vous tapez la lettre “h” par exemple, vous aurez accès à l'aide qui liste les commandes disponibles:

Parmi les commandes d'usage courant, on notera

  • u” qui permet de restreindre l'affichage à un utilisateur particulier
  • k” qui permet de tuer un processus en donnant son pid (confirmation requise)
  • r” qui permet de changer la priorité d'un processus (“renice”).
  • F” ou “O” qui permettent de changer la colonne qui détermine l'ordre des processus (charge cpu par défaut).
  • q” pour… quitter “top”.

Voilà pour le petit tour d'horizon de la commande top, mais sachez qu'il existe d'autres options et que l'interaction pendant son exécution est grande. Je vous invite à explorer le manuel si cela vous intéresse.

<note>Il existe des versions “évoluées” ou alternatives de top : htop et atop dont le seul inconvénient par rapport à top est qu'il soit nécessaire de les installer pour les utiliser… Mais cela vaut le coup d'essayer ! Consultez cette page pour plus d'informations.</note>

Les commandes jobs, bg et fg

<note important>les commandes bg, fg, jobs sont des commandes propres au shell que vous avez lancé. Les exemples donnés ci-dessous ont été effectués sur bash, qui est le shell le plus utilisé. Si vous utilisez un autre shell, il faudra vous référez au manuel de celui-ci pour avoir plus de renseignement sur le contrôle des taches.</note>

On peut mettre une commande en “arrière-plan”, c'est-à-dire que, une fois lancée, la commande ne nous bloquera pas la console jusqu'à ce qu'elle soit finie (ce qui devrait être le comportement normal) et agira sans que nous soyons obligé de nous en soucier.
Un exemple simple : je suis en console, je veux copier l'intégralité de mon disque 1 vers mon disque 2, et je sais que j'ai de multiples musiques et films libres qui prennent beaucoup de place. Le transfert sera donc très long et je ne veux pas attendre pour taper d'autres commandes en parallèle.

On utilise l'esperluette & en fin de commande pour qu'elle soit lancée en arrière-plan :

$ cp /toutesmesdonnees /chemin/de/destination &

Une fois que cela est fait, j'aimerais tout de même savoir de temps en temps où en sont mes commandes passées en arrière-plan. Il me suffit de taper la commande jobs (“travaux” en français) pour connaître toutes les commandes lancées en arrière-plan (ici, deux recherches avec la commande find).

$ jobs 
[1]-  Running                 find / -iname truc &
[2]+  Running                 find / -iname machin &

On pourra noter que chaque commande est numérotée (ici 1 et 2). C'est ce numéro d'identification qui va nous servir par la suite. <note>Le numéro donné par job et le numéro d'un processus donné par top n'ont rien à voir. Le premier sert aux commandes lancées dans un shell, l'autre est pour le noyau. Ils n'ont donc pas la même signification, mais aussi et surtout la même référence !</note>

Pour maintenant remettre une commande au premier plan, je peux utiliser la commande fg (pour “foreground”, “premier-plan” en anglais). Là, trois solutions :

  • Soit je n'ai qu'une commande en arrière-plan, et je peux utiliser fg sans argument,
  • Soit j'ai plusieurs commandes en arrière-plan, et j'utilise alors le numéro donné par jobs pour savoir quelle commande je désire récupérer.

Voici donc un exemple. Si je veux revoir au premier plan la recherche de “machin” (donc le job numéro 2) :

$ fg %2

Notez bien l'utilisation de %, c'est obligatoire pour que fg trouve bien le bon processus.

C'est maintenant que les choses se corsent … Maintenant que j'ai récupéré la main sur ma commande de recherche de “machin”, je crois comprendre que je vais en avoir pour un certains temps. Je veux donc à nouveau le remettre en arrière-plan. Pour cela, je vais le stopper, pour récupérer la main sur le shell, puis lui dire de continuer en arrière plan, grâce à la commande bg (pour “background”, “arrière plan” en anglais). Voici donc les manipulations :

  1. Pour stopper le processus actuellement en premier-plan, il faut faire contrôle-z (maintenez la touche ctrl et appuyez sur z) noté aussi ^z.
  2. Vérifier le numéro assigné à ce processus, à l'aide de jobs (vous pouvez remarqué qu'il est indiqué comme “stopped”, c'est-à-dire arrêté) :
    $ jobs
    [1]-  Running                 find / -name truc &
    [2]+  Stopped                 find / -name machin
  3. Puis relancez-le en arrière-plan avec bg (j'utilise le numéro 2 ici):
$ bg %2

La commande kill

La commande kill va nous servir à envoyer un signal à un processus en cours d'exécution. Cette commande est puissante, attention donc à ne pas faire n'importe quoi avec. Elle peut donc utiliser les numéros donnés par jobs et ainsi arrêter un processus. Pour arrêter ma recherche sur “machin” (voir chapitre ci-dessus), il me suffit donc d'écrire :

$ kill %2

Le processus sera alors arrêté.

“kill” peut prendre en argument le PID d'un processus, tel que renvoyé par “top” ou “pgrep”. Prenons l'exemple d'une recherche du PID de “konqueror” (navigateur de fichiers/web KDE), et de son utilisation avec “kill”:

$ pgrep -l konqueror
9656 konqueror
$ kill 9656

Par défaut “kill” envoie le signal “SIGTERM” (option ”-15”), qui est reçu par le programme visé, et lui indique de se terminer proprement. Il peut arriver que ce signal soit inefficace si le programme est totalement “gelé”, dans ce cas on utilisera l'option “-9” qui envoie le signal “SIGKILL”. Ce signal n'est pas reçu par le programme, c'est le noyau qui termine immédiatement le processus, ce qui peut laisser “traîner” des processus fils orphelins, entraîner la perte du travail en cours dans le programme visé… À n'utiliser que dans les cas désespérés:

$ kill -9 9565

“kill” peut envoyer de nombreux autres signaux, ils sont détaillés dans la page de manuel de “kill”. En plus des deux précédemment cités “TERM” (option “-15”) et “KILL” (option “-9”), on peut retenir “HUP” (option -1) qui est utile pour les services (samba, sshd,…). “HUP” va entraîner le redémarrage du service visé après relecture des fichiers de configuration, utile pour prendre en compte un changement de configuration.

Pour indiquer de manière plus “conviviale” le nom du programme visé au lieu de son PID, on peut utiliser la commande “killall”:

$ killall konqueror

Attention au fait que si plusieurs processus de même nom existent, tous seront terminés.

<note> Si le programme/processus visé par “kill” appartient à un utilisateur différent du votre, ou à “root”, vous devrez employer “kill” avec des droits “root”. Attention dans ce cas car “kill” pourra alors interrompre n'importe quel processus, et littéralement couper la branche sur laquelle vous êtes assis…</note>

Pour les curieux : "kill" ou "/bin/kill" ?

Il est fort possible que vous ayez deux commandes “kill” sur votre ordinateur : l'une provient des commandes internes de votre shell (bash par exemple), l'autre est un paquet à part entière (sans doute dans /bin/kill ou /sbin/kill).
Il existe quelques moyens simples de savoir à quelle commande on fait réellement appel, pour voir où se trouve le programme “kill” autonome faite :

$ which kill
/bin/kill

Pour voir si votre interpréteur de commande, ici “bash”, contient également la commande “kill”, vous pouvez rechercher le motif “kill” à l'intérieur du programme “bash” :

$ strings /bin/bash | grep kill
[...]
kill_builtin
kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
    you can create, you don't have to start a process to kill another one.
    signal can be sent to the shell with "kill -signal $$".
[...]

Cela vous renverra de nombreuses informations, ici seul le plus intéressant a été conservé. La commande “strings” recherche dans un programme binaire le contenu “humainement compréhensible” (“human readable” en Anglais), nous voyons donc que “bash” contient bien une commande “kill”. Confirmation avec la commande “type” :

$ type kill
kill is a shell builtin

$ type `which kill`
/bin/kill is /bin/kill

Ça n'est pas primordial de savoir à quelle commande vous faites appel, mais par exemple si vous écrivez des scripts il peut être intéressant de faire appel préférentiellement à l'une ou l'autre version.

Pour en savoir plus sur les commandes intégrées à l'interpréteur de commande Bash (“builtin commands”), consultez:
Listes des commandes intégrées (eng)
ainsi que le manuel de bash.

commande/job_control.txt · Dernière modification: 2018/11/17 13:52 (modification externe)