Chaque application, chaque commande est un processus.
Certains processus vont s’exécuter jusqu’à ce que vous les arrêtiez, d’autres vont réaliser une tâche et s’arrêter tout seul.
Exemple:
La commande ls
: elle s’exécute et se termine tout de suite. Vous pouvez taper une autre commande.
La commande firefox
: elle ouvre Firefox mais reste en exécution jusqu’à ce que vous fermiez Firefox. Notez que vous ne pouvez plus utiliser votre terminal tant que Firefox fonctionne.
Comment faire pour lancer Firefox et pouvoir continuer à utiliser le terminal?
Quand une commande vous empêche d’utiliser le terminal pendant son exécution, c’est parce qu’elle s’exécute au premier plan.
Comment faire pour qu’une application s’exécute en arrière plan?
Deux possibilités:
&
:$ firefox &
Si la commande s’exécute déjà et que vous souhaitez la passer en arrière plan, vous devez d’abord faire Ctrl-z
pour stopper l’application. Notez alors que vous pouvez utiliser votre terminal mais le programme, lui n’est plus utilisable. Tapez ensuite bg
(pour background), le programme va alors s’exécuter en arrière plan.
Comment faire pour remettre la commande au premier plan? Avec fg
(pour foreground).
Lancez Firefox puis faites le passer en arrière plan et ramenez le au premier plan.
Pour arrêter une commande au premier plan: Ctrl-c
Tout d’abord, la commande permettant d’afficher les processus:
$ ps -f
Si vous entrez cette commande, vous voyez que les processus sont identifiés par deux numéros: pid
et ppid
:
pid
: identifiant du processus
ppid
: identifiant du processus père
Le processus père est le processus qui les a créé.
Exemple:
Si vous lancez une commande depuis votre terminal, celui-ci sera le père de la commande que vous venez de lancer.
Avec ps, notez le pid
de votre shell. Lancez Firefox. Quel est le pid
de Firefox? Quel est le pid
du père de Firefox?
Que se passe-t-il si on tue le père d’un processus?
Il sera adopté par le processus 1.
Comment se nomme le processus 1?
Il est donc possible de créer un arbre généalogique avec tous les processus.
L’arborescence des processus s’obtient avec:
$ pstree
Lancez Firefox en tâche de fond à l’aide de la ligne de commande, notez son pid
et son ppid
(le ppid
devrait être votre SHELL).
Fermez le terminal puis ouvrez-en un nouveau.
Quel est le ppid
de Firefox maintenant?
Un processus peut être dans plusieurs états:
Élu: c’est lui qui est sur le processeur, en cours d’exécution.
Prêt: il est dans la file d’attente du processeur, il n’est en attente d’aucune ressource.
Bloqué: il est en attente d’une ressource autre que le processeur (disque par exemple).
Zombie: le processus est mort mais son père n’a pas encore pris en compte sa mort. Il y a toujours une entrée le concernant dans la table des processus.
Ces différents états sont gérés par l’ordonnanceur.
Pour afficher les processus et leur utilisation des ressources:
$ top
À quelle fréquence se rafraîchit top
? Comment obtenir un rafraîchissement toutes les secondes?
L’autre commande que nous avons vu est ps
.
Pour arrêter des processus:
$ kill pid
kill
peut avoir différents paramètres. Pour tuer un processus immédiatement:
$ kill -9 pid
killall
peut détruire tous les processus ayant le même nom:
$ killall httpd
Il est aussi possible d’attendre la fin d’une commande avant d’en exécuter une autre même si celle-ci a été lancée en arrière plan.
Exemple:
$ firefox & wait $!
Ou encore, dans un script:
firefox & wait $! echo "Fin du script"
Si vous exécutez un processus à partir du terminal, la fermeture du terminal entraine la fin du processus.
Pour éviter ce comportement, deux possibilités existent:
Une fois le processus démarré:
$ disown <pid>
Au lancement de la commande:
$ nohup <commande>
$ gedit
Notez que cette commande s’exécute tant que vous ne fermez pas le fenêtre.
Ouvrez un autre terminal, trouvez le pid
de la commande gedit
et tuez la commande.
$ disown
$ nohup firefox
Une commande peut s’exécuter correctement mais peut aussi se terminer avec une erreur.
Chaque commande va donc avoir une valeur de retour qui permet de savoir s’il y a eu une erreur ou non.
Par convention, si la valeur de retour de la commande est 0, la commande s’est exécutée correctement sans erreur.
S’il y a des erreurs, la valeur de retour sera différente de 0.
Certaines variables sont réservées par le système pour des significations particulières.
Il sera ainsi possible de connaitre la valeur de retour de la dernière commande:
$ echo $?
Ou de connaitre le PID
de la dernière commande lancée en tâche de fond:
$ echo $!
Lancez la commande ls
. Quel est son code de retour? Est-ce un succès ou un échec?
Sans être root, lancez la commande $ find / -name “*.conf”
. Quel est son code de retour? Pourquoi?
Il est possible de combiner des commandes. Nous avons déjà vu le | mais il y a d’autres possibilités.
$ Commande 1 ; Commande 2 ; …
Permet d’enchainer les commandes les unes après les autres.
$ Commande 1 && Commande 2
Exécutera Commande 2 seulement si Commande 1 s’est exécutée avec succès et n’a pas renvoyé d’erreur.
$ Commande 1 || Commande 2
Exécutera Commande 2 seulement si Commande 1 a eu un problème et a renvoyé une erreur.
Exemples:
Tester l’existence d’un fichier et exécuter la commande le cas échéant:
$ test -e fichier && commande
Afficher un message OK si la commande a réussi:
$ commande && echo OK
Ou bien afficher un message d’erreur si la commande .choue:
$ commande || echo ERREUR
Et enfin, afficher OK si le code de retour est 0 ou ERREUR si le code de retour est différent de 0 :
$ Commande 1 && echo OK || echo ERREUR
Exemple :
$ test $var -eq 0 && echo "$var = 0" || echo "$var != 0"
La commande s’exécute en tâche de fond (arrière plan), vous récupérez la main.
$ Commande 1 &
Les commandes s’exécutent de façon asynchrone, totalement indépendamment l’une de l’autre.
$ Commande 1 & Commande 2
$ find / -name "*.conf" && ls
$ find / -name "*.conf" || ls
$ find / -name "*.conf" & ls
Il est possible d’utiliser des () pour déterminer la priorité des opérateurs &, &&, |, || et ;
Exemple:
ls
est exécutée s’il y a une erreur avec find et le résultat de la ou des commande(s) exécutée(s) sera filtré par grep:
$ (find / -name "*.conf" 2>/dev/null || ls) | grep a
ls
sera exécuté s’il y a une erreur avec find et le résultat de ls seulement sera filtré par grep
:
$ find / -name "*.conf" 2>/dev/null || (ls | grep a)
Rappel:
$ $(commande)
permet de stocker le résultat d’une commande dans une variable.
Exemple:
La commande suivante permet de stocker le résultat de la commande find dans la variable var.
$ var=$(find / -name "*.conf")
$ echo $var
Cette enchainement donne le même affichage que mais le résultat est réutilisable:
$ find / -name "*.conf"
Pour chercher dans le contenu de plusieurs fichiers :
$ egrep <chaine> <fichiers>
$ egrep ssh *
Pour connaître l’espace disque:
$ df [-h]
Pour connaître la taille d’un fichier ou d’un répertoire:
$ du [-sh] répertoire
Pour connaître l’état de la mémoire:
$ free