Оскільки ви згадуєте, ви вирішили проблему для вашої конкретної ситуації, нижче - рішення загального призначення. Завдяки опції xdotool
'' --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
сеанс, прихований файл, створений сценарієм, буде просто перезаписаний, тому не потрібно видаляти його інакше.