Isso porque gnome-terminal
é "inteligente". Quando você acionar gnome-terminal
, ele determinará se outra instância de gnome-terminal
já está em execução.
- Se não, cria um novo processo
gnome-terminal
e gera uma janela. - Se sim, simplesmente fará com que o processo
gnome-terminal
existente crie uma nova janela.
Portanto, todas gnome-terminal
janelas são executadas como um único processo, com um único PID.
Você pode facilmente verificar isso abrindo várias gnome-terminal
janelas, então pegue seus PIDs emitindo xprop _NET_WM_PID
em algum lugar e clique dentro deles. Você verá que o PID é o mesmo para todas as janelas.
Então, o que acontece no seu roteiro?
Você está capturando os PIDs das instâncias de gnome-terminal
que você inicia bem, mas o problema é que esses PIDs existem apenas por uma fração de segundo. Esses processos apenas fazem com que o processo gnome-terminal
existente crie uma nova janela e termine.
Então, se você já tem um processo gnome-terminal
ativo ao executar seu script (o que eu suponho), os PIDs que você coletou não existem mais quando você tenta matá-los. Se você não o fizer (digamos, você executar esse script de um xterm
ou algum outro emulador de terminal), o primeiro PID que você coletar estará de fato "correto". Os seguintes PIDs que você coletar serão "incorretos". Uma vez que você insere o loop de eliminação, a primeira iteração mataria todas as gnome-terminal
windows e as seguintes resultariam em erros, porque esses PIDs não existem mais.
Então, como resolver isso?
Bem, de cara, posso pensar em duas maneiras.
-
Se você não insistir em usar
gnome-terminal
, use outro emulador de terminal que não se comporte dessa maneira.xterm
, por exemplo, gera um processo separado para cada janela. Se você usarxterm
em vez degnome-terminal
em seu script, isso deve funcionar. Fácil & amp; limpo. -
Se você insistir em usar
gnome-terminal
, a maneira de matar uma janelagnome-terminal
específica seria matar o processo que está sendo executado dentro dessa janela específica. Assim que você terminar esse processo, essa janela será fechada. Mas como você está usando a opção-e
, esse processo seránetcat $ipaddress $port
primeiro, depoisbash
, e é difícil obter os PIDs. Você não pode coletá-los facilmente como está fazendo atualmente com$!
. Você poderia tentar algo comokillall netcat
oukillall bash
, mas claramente isso também terminaria todas as outras instâncias denetcat
oubash
, o que você provavelmente não deseja. Você poderia, possivelmente,grep
sobre uma chamadaps
habilmente projetada para tentar encontrar os PIDs exatos que deseja matar, mas isso é instável e propenso a erros. Honestamente, eu iria apenas para a solução 1.
Dois pequenos comentários no seu script:
-
Linha 10: deve ser
port=0
, não$port=0
. -
Linha 13: deve ser
processarray+=("$!")
, nãoprocessarray+= ("$!")
.
Espero que ajude.
Editar: Acabei de encontrar a opção --disable-factory
para gnome-terminal
, o que faz com que não reutilize processos existentes. Aqui está o seu script fixo:
#!/bin/bash
ipaddress=
port=
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