J'ai écrit un script bash qui appelle plusieurs autres programmes et exécute un tas de commandes. Je lance ce script depuis le terminal. Maintenant, je veux tuer le script.
Appuyer sur Ctrl + C
ne suffit parfois pas, le script exécute un autre programme et, pour une raison quelconque, le signal de suppression ne fonctionne pas.
Cependant, si je ferme la fenêtre du terminal, le script est tué.
Est-ce que je peux faire quelque chose (une combinaison de clavier), analogue à la fermeture de la fenêtre du terminal, sans fermer celle-ci (je ne veux pas perdre l'historique des commandes, le répertoire actuel, l'historique de sortie, etc.)?
Vous avez peu d'options. La première consiste à arrêter le script (CtrlZ), obtenez le PID du script et envoyez SIGKILL
au groupe de processus.
Lorsqu'une commande est exécutée dans un shell, le processus qu'il démarre commence et tous ses enfants font partie du même groupe de processus ( dans ce cas, le groupe de processus de premier plan). Pour envoyer un signal à tous les processus de ce groupe, vous l'envoyez au responsable du processus. Pour la commande kill
, le responsable du processus est désigné ainsi:
kill -PID
Où PID
est l'ID de processus du script.
Exemple:
Prenons un script test.sh
qui lance certains processus. Disons que vous l'avez exécuté dans un shell:
$ ./test.sh
Dans un autre terminal,
$ pgrep test.sh
17802
$ pstree -ps `!!`
pstree -ps `pgrep test.sh`
init(1)───sshd(1211)───sshd(17312)───sshd(17372)───zsh(17788)───test.sh(17802)─┬─dd(17804)
├─sleep(17805)
└─yes(17803)
Dans ce cas, pour envoyer un signal au groupe de processus créé par test.sh
, procédez comme suit:
kill -INT -17802
-INT
est utilisé pour envoyer SIGINT
et cette commande équivaut donc à appuyer sur CtrlC sur le terminal. Pour envoyer SIGKILL
:
kill -KILL -17802
Vous ne devez arrêter le script que si vous ne pouvez pas ouvrir un autre terminal. Si vous le pouvez, utilisez pgrep
pour trouver le PID.
L’une des commandes lancées par le script peut intercepter SIGINT
, ce qui explique probablement pourquoi CtrlC est inefficace. Cependant, SIGKILL
ne peut pas être intercepté et il s’agit généralement d’une option de dernier recours . Vous voudrez peut-être essayer SIGTERM
(-TERM
) avant de tuer. Ni SIGKILL
ni SIGTERM
ne peuvent être configurés comme raccourci clavier comme SIGINT
est.
Tout cela n'a plus sa raison d'être si votre script ne contient pas de ligne Shebang. De this SO answer :
Généralement, le shell parent suppose que le script est écrit pour le même shell (des shells de type Bourne ressemblent au script avec/bin/sh, bash l’exécute en tant que sous-processus bash) ...
De ce fait, lorsque le script est exécuté, vous ne trouverez pas de processus nommé après le script (ni un processus avec le nom du script dans la ligne de commande) et pgrep
échouera.
Toujours utiliser une ligne Shebang.
Si vous connaissez les processus associés au script, vous pouvez trouver leur PID en utilisant
ps -A
puis utilisez le numéro PID pour tuer les processus correspondants à l'aide de
kill -9 PID_Number
Comme Harris l'a dit, vous pouvez exécuter Kill -9 PID_Number
, mais vous pouvez également installer le package appelé htop
afin de disposer d'un navigateur de processus interactif facilitant grandement la recherche de processus spécifiques. htop prend également en charge les processus de mise à mort.