Desde que você mencionou, resolveu o problema para sua situação específica, abaixo de uma solução para propósitos gerais. Graças à opção xdotool
do --sync
, funciona bastante confiável nos testes que executei; Eu poderia "enviar" comandos para janelas de terminal específicas e ele funcionava perfeitamente sem uma exceção.
Como funciona na prática
A solução existe em um script, que pode ser executado com duas opções
-set
e -run
:
-
Para definir para cima (abrir) um número arbitrário de janelas de terminal, neste exemplo 3:
target_term -set 3
Três novos terminais serão abertos, o ID da janela é lembrado em um arquivo oculto:
Por motivos de clareza, eu minimizei a janela do terminal. Eu executei o comando de:)
-
Agora que criei três janelas, posso enviar comandos para qualquer uma delas com o comando run (por exemplo):
target_term -run 2 echo "Monkey eats banana since it ran out of peanuts"
Como mostrado abaixo, o comando foi executado no segundo terminal:
Posteriormente, posso enviar um comando para o primeiro terminal:
target_term -run 1 sudo apt-get update
fazendo com que
sudo apt-get update
seja executado no terminal 1:e assim por diante ...
Como configurar
-
O script precisa dos dois
wmctrl
exdotool
:sudo apt-get install wmctrl xdotool
-
Copie o script abaixo em um arquivo vazio, como
target_term
(sem extensão!) em~/bin
(crie o diretório~/bin
, se necessário. -
Torne o script executável (não esqueça) e efetue logout / in ou execute:
source ~/.profile
-
Agora configure suas janelas de terminal com o número de janelas necessárias como argumento:
target_term -set <number_of_windows>
-
Agora você pode "enviar" comandos para qualquer um dos seus terminais com o comando:
target_term -run <terminal_number> <command_to_run>
O script
#!/usr/bin/env python3
import subprocess
import os
import sys
import time
#--- set your terminal below
application = "gnome-terminal"
#---
option = sys.argv[1]
data = os.environ["HOME"]+"/.term_list"
def current_windows():
w_list = subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8")
w_lines = [l for l in w_list.splitlines()]
try:
pid = subprocess.check_output(["pgrep", application]).decode("utf-8").strip()
return [l for l in w_lines if str(pid) in l]
except subprocess.CalledProcessError:
return []
def arr_windows(n):
w_count1 = current_windows()
for requested in range(n):
subprocess.Popen([application])
called = []
while len(called) < n:
time.sleep(1)
w_count2 = current_windows()
add = [w for w in w_count2 if not w in w_count1]
[called.append(w.split()[0]) for w in add if not w in called]
w_count1 = w_count2
return called
def run_intterm(w, command):
subprocess.call(["xdotool", "windowfocus", "--sync", w])
subprocess.call(["xdotool", "type", command+"\n"])
if option == "-set":
open(data, "w").write("")
n = int(sys.argv[2])
new = arr_windows(n)
for w in new:
open(data, "a").write(w+"\n")
elif option == "-run":
t_term = open(data).read().splitlines()[int(sys.argv[2])-1]
command = (" ").join(sys.argv[3:])
run_intterm(t_term, command)
Notas
-
O script está definido para
gnome-terminal
, mas pode ser usado para qualquer terminal (ou outro programa também) alterando oapplication
na seção head do script:#--- set your terminal below application = "gnome-terminal" #---
- Os comandos acima podem (é claro) ser executados a partir de um script, caso você queira usá-lo para algum tipo de simulação.
- O script aguarda até que a janela de destino tenha foco e o comando seja feito com digitação, para que o comando sempre caia na janela do terminal à direita.
-
Não há necessidade de dizer que o script só funciona com a configuração do terminal (windows) que foi chamada pelo comando:
target_term -set
As janelas do terminal serão então "rotuladas" pelo script, como você mencionou na sua pergunta.
- Caso você inicie uma nova sessão
target_term
, o arquivo oculto, criado pelo script, será simplesmente sobrescrito, portanto, não há necessidade de removê-lo de outra forma.