เนื่องจากคุณพูดถึงว่าคุณได้แก้ไขปัญหาสำหรับสถานการณ์เฉพาะของคุณด้านล่างโซลูชันสำหรับวัตถุประสงค์ทั่วไป ขอขอบคุณที่xdotool
เป็น--sync
ตัวเลือกที่จะทำงานได้สวยน่าเชื่อถือในการทดสอบฉันวิ่ง; ฉันสามารถ "ส่ง" คำสั่งไปยังหน้าต่างเทอร์มินัลเฉพาะและมันทำงานได้อย่างสมบูรณ์แบบโดยไม่มีข้อยกเว้น
มันทำงานอย่างไรในทางปฏิบัติ
โซลูชันมีมาจากสคริปต์ซึ่งสามารถรันด้วยสองตัวเลือก
-set
และ-run
:
ในการตั้งค่า (เปิด) จำนวนเทอร์มินัล windows ในตัวอย่างนี้ 3:
target_term -set 3
สามเทอร์มินัลใหม่จะเปิดขึ้น id หน้าต่างจะถูกจดจำในไฟล์ที่ซ่อนอยู่:
เพื่อเหตุผลที่ชัดเจนฉันย่อเล็กสุดหน้าต่างเทอร์มินัลฉันรันคำสั่งจาก :)
ตอนนี้ฉันสร้างหน้าต่างสามบานฉันสามารถส่งคำสั่งไปยังหนึ่งในนั้นด้วยคำสั่ง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
ทำงานใน terminal 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
เซสชันใหม่ไฟล์ที่ถูกซ่อนซึ่งสร้างโดยสคริปต์จะถูกเขียนทับจึงไม่จำเป็นต้องลบออก