Поскольку вы упоминаете, что решили проблему для конкретной ситуации, ниже приведено решение для общего назначения. Благодаря xdotool
«S --sync
вариант, он работает довольно надежен в тестах я побежал; Я мог «отправлять» команды в определенные окна терминала, и он работал без исключений.
Как это работает на практике
Решение существует из сценария, который может быть запущен с двумя вариантами
-set
и -run
:
Чтобы установить (открыть) произвольное количество окон терминала, в этом примере 3:
target_term -set 3
Откроются три новых терминала, их идентификатор окна запомнен в скрытом файле:
Для ясности я свернул окно терминала, из которого запускал команду :)
Теперь, когда я создал три окна, я могу отправлять команды любому из них с помощью команды run (например):
target_term -run 2 echo "Monkey eats banana since it ran out of peanuts"
Как показано ниже, команда выполняется во втором терминале:
Впоследствии я могу отправить команду на первый терминал:
target_term -run 1 sudo apt-get update
решений на sudo apt-get update
работы в терминале 1:
и так далее...
Как настроить
Скрипту нужны оба wmctrl
и xdotool
:
sudo apt-get install wmctrl xdotool
Скопируйте приведенный ниже скрипт в пустой файл, сохраните его как target_term
(без расширения!) В ~/bin
(создайте каталог, ~/bin
если это необходимо.
Сделайте скрипт исполняемым (не забудьте) и выйдите из системы, войдите в нее или запустите:
source ~/.profile
Теперь настройте окна терминала, указав в качестве аргумента количество необходимых окон:
target_term -set <number_of_windows>
Теперь вы можете «отправлять» команды на любой из ваших терминалов с помощью команды:
target_term -run <terminal_number> <command_to_run>
Сценарий
#!/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)
Примечания
Скрипт установлен для gnome-terminal
, но может использоваться для любого терминала (или другой программы), изменив application
в разделе заголовка скрипта:
#--- set your terminal below
application = "gnome-terminal"
#---
- Вышеприведенные команды могут (конечно) также запускаться из скрипта, если вы захотите использовать его для какой-то симуляции.
- Сценарий ожидает, пока целевое окно не будет сфокусировано, и команда не завершит набор текста, поэтому команда всегда будет находиться в правом окне терминала.
Не нужно говорить, что скрипт работает только с настройками терминала (windows), которые были вызваны командой:
target_term -set
Окна терминала будут «помечены» сценарием, как вы упомянули в своем вопросе.
- Если вы начинаете новый
target_term
сеанс, скрытый файл, созданный сценарием, будет просто перезаписан, поэтому нет необходимости удалять его в противном случае.