J'essaie de créer un script qui ouvre plusieurs terminaux gnome et ouvre une connexion netcat. Après quelques secondes, j'aimerais que les terminaux se ferment. Je suis désemparé et je crois que cela ne peut être fait, mais je me suis dit que je le demanderais.
C’est ce que j’ai fait jusqu’à présent. Cependant, une fois que je l’ai exécuté, les identifiants de processus sont considérés comme incorrects et je pense que c’est parce que gnome-terminal impose le processus à bash et que je ne capture pas ce pid.
ipaddress=$1
port=$2
processarray=()
echo "netcat command set to ip: $ipaddress and port: $port"
if [ -z "$ipaddress" ]; then
echo "No ip address entered"
fi
if [ -z "$port" ]; then
echo "No port entered default set to 0"
$port=0
fi
for i in {0..9}; do
gnome-terminal -e "bash -c \"netcat $ipaddress $port; exec bash\"" & processarray+= ("$!")
done
sleep 10;
for i in "${processarray[@]}"; do
kill "$i"
done
C'est parce que gnome-terminal
est "intelligent". Lorsque vous lancez gnome-terminal
, il déterminera si une autre instance de gnome-terminal
est déjà en cours d'exécution.
gnome-terminal
et génère une fenêtre.gnome-terminal
existant générera simplement une nouvelle fenêtre.Par conséquent, toutes les fenêtres gnome-terminal
s'exécutent en tant que processus unique avec un seul PID.
Vous pouvez facilement vérifier cela en ouvrant plusieurs fenêtres gnome-terminal
, puis obtenir leurs PID en émettant xprop _NET_WM_PID
quelque part et en cliquant à l'intérieur. Vous verrez que le PID est le même pour toutes les fenêtres.
Alors, que se passe-t-il dans votre script?
Vous capturez les PID des instances gnome-terminal
que vous lancez correctement, mais le problème est que ces PID n'existent que pour une fraction de seconde. Ces processus entraînent uniquement le processus gnome-terminal
existant à générer une nouvelle fenêtre, puis à se terminer.
Donc, si vous avez déjà un processus actif gnome-terminal
lors de l’exécution de votre script (ce que je suppose), les PID que vous collectez n’existent plus lorsque vous essayez de les tuer. Si vous ne le faites pas (par exemple, vous exécutez ce script à partir d'un xterm
ou d'un autre émulateur de terminal), le premier PID que vous collectez sera en effet "correct". Les PID suivants que vous collectez seront "incorrects". Une fois que vous entrez dans votre boucle de destruction, la première itération tuera toutes les fenêtres gnome-terminal
et les suivantes produiront des erreurs, car ces PID n'existent plus.
Alors, comment résoudre ce problème?
Bien, dès le départ, je peux penser à deux façons.
Si vous n'insistez pas pour utiliser gnome-terminal
, utilisez plutôt un autre émulateur de terminal qui ne se comporte pas de cette manière. xterm
crée par exemple un processus distinct pour chaque fenêtre. Si vous utilisez xterm
plutôt que gnome-terminal
dans votre script, cela devrait fonctionner. Nettoyage facile.
Si vous insistez pour utiliser gnome-terminal
, le moyen de tuer une fenêtre spécifique gnome-terminal
serait de tuer le processus en cours d'exécution dans cette fenêtre spécifique. Dès que vous terminez ce processus, cette fenêtre se ferme. Mais puisque vous utilisez cette option -e
, ce processus sera d'abord netcat $ipaddress $port
, puis bash
, et il est difficile d'obtenir les PID. Vous ne pouvez pas facilement les collecter comme vous le faites actuellement avec $!
. Vous pouvez essayer quelque chose comme killall netcat
ou killall bash
, mais il est clair que cela mettra également fin à toutes les autres instances netcat
ou bash
, que vous ne voudrez probablement pas. Vous pouvez éventuellement grep
utiliser un appel ps
intelligemment conçu pour essayer de trouver les PID exacts que vous voulez tuer, mais c'est fragile et sujet aux erreurs. Honnêtement, je voudrais juste aller pour la solution 1.
Deux commentaires mineurs sur votre script:
Ligne 10: Ce devrait être port=0
, pas $port=0
.
Ligne 13: Ce devrait être processarray+=("$!")
, pas processarray+= ("$!")
.
J'espère que ça t'as aidé.
Edit: Oh, je viens de trouver l’option --disable-factory
pour gnome-terminal
, ce qui l’empêche de réutiliser les processus existants. Voici votre script fixe:
#!/bin/bash
ipaddress=$1
port=$2
processarray=()
echo "netcat command set to ip: $ipaddress and port: $port"
if [ -z "$ipaddress" ]; then
echo "No ip address entered"
fi
if [ -z "$port" ]; then
echo "No port entered default set to 0"
port=0
fi
for i in {0..9}; do
gnome-terminal --disable-factory -e "bash -c \"netcat $ipaddress $port; exec bash\"" & processarray+=("$!")
done
sleep 10;
for i in "${processarray[@]}"; do
kill "$i"
done