Belirli terminal pencerelerine nasıl komut gönderebilirim?


13


Ayrı terminallerde aynı anda birden fazla program (sunucu) açmak için bir komut dosyası yazmak istiyorum - hangisi önemli değil - ve doğru terminalin içinde "iniş" komutlarıyla farklı terminallere farklı komutlar atamak istiyorum. Mümkün mü?
Belki böyle bir şey:

  1. açık terminal1
  2. terminal2 // 1 ile eşzamanlı olarak açın.
  3. command1 // yeni bir terminal penceresi açmadan terminal1'de yürüt
  4. command2 // yeni bir terminal penceresi açmadan terminal2'de çalıştır
  5. ...

Bir şekilde terminal pencerelerini etiketleyebilir miyim, böylece komutlar doğru terminal içinde yürütülüyor mu?

Programları çalışırken tüm terminalleri izlemek istiyorum - programlarımın terminalde izleme / hata ayıklama için bir argümanı var. Bu yüzden, aralarında hangi mesajların paylaşıldığını görmek istiyorum.

NOT: Bu komut dosyası "simülasyon" görevi görmesi gerektiğinden, değiştirilen verilerin güvenliği konusunda daha az endişeliyim. Her sunucuyu localhost üzerinde ayrılan bir bağlantı noktasından çalışacak şekilde yapılandırdım.


Kontrol pssh ....
heemayl

Zamanlama ne kadar doğru olmalıdır; diyelim ki 2 saniye (her terminal için) uygun mudur?
Jacob Vlijm

@JacobVlijm: "pencere" terminaline göre komutları doğru şekilde atamak benim için daha önemli
Aliakbar Ahmadi

1
Özellikle simülasyon söz konusu olduğunda yapılabilir, geri gönderecek :)
Jacob Vlijm

1
@JacomVlijm: aslında benim sorum tesadüfen çözüldü: doğru örneğine bir komut göndermek için her komutun o vakanın başladığı datadir ile öneki olması gerekir! Ama şansım için bu bitcoin içinde uygulanır ama ben sadece soruyu cevapsız bırakacağım .. belki birisi herhangi bir program için daha genel bir fikir bulur !? :) Ama yine de teşekkürler!
Aliakbar Ahmadi

Yanıtlar:


14

Bahsettiğinizden, genel durum için bir çözümün altında, özel durumunuz için sorunu çözdüğünüzden emin olun. Sayesinde xdotoolbireyin --syncseçeneği, bu Koştum testlerde oldukça güvenilir çalışır; Belirli terminal pencerelerine "gönderebilir" ve istisnasız mükemmel çalıştı.

Pratikte nasıl çalışır?

Çözelti iki seçenekli çalıştırılabilir Filmin senaryosu ise mevcut -setve -run:

  1. İçin ayarlanmış Bu örnek 3'te, uç pencere rasgele bir sayı (açık) kadar:

    target_term -set 3

    Üç yeni terminal açılacak, pencere kimlikleri gizli bir dosyada hatırlanacak:

    resim açıklamasını buraya girin

    Açıklık nedeniyle, terminal penceresini simge durumuna küçültdüm.

  2. Şimdi üç pencere oluşturduğumdan, çalıştır komutuyla bunlardan birine komut gönderebilirim (örn.):

    target_term -run 2 echo "Monkey eats banana since it ran out of peanuts"

    Aşağıda gösterildiği gibi, komut ikinci terminalde koştu:

    resim açıklamasını buraya girin

    Daha sonra, ilk terminale bir komut gönderebilirim:

     target_term -run 1 sudo apt-get update

    yapmada sudo apt-get updateTerminal 1 çalıştırmak:

    resim açıklamasını buraya girin

    ve bunun gibi...

Nasıl kurulur

  1. Senaryo hem ihtiyacı wmctrlve xdotool:

    sudo apt-get install wmctrl xdotool
  2. Aşağıdaki komut dosyasını boş bir dosyaya kopyalayın ( gerekirse dizini oluşturun target_term) içinde ~/bin( uzantı yok!)~/bin

  3. Komut dosyasını yürütülebilir yapın (unutmayın) ve oturumu kapatın / oturum açın veya çalıştırın:

    source ~/.profile
  4. Şimdi terminal pencerelerinizi bağımsız değişken olarak gerekli pencerelerin sayısı ile ayarlayın:

    target_term -set <number_of_windows>
  5. Şimdi şu komutlarla terminallerden birine "gönderebilirsiniz":

    target_term -run <terminal_number> <command_to_run>

Senaryo

#!/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)

notlar

  • Betik ayarlanmıştır gnome-terminal, ancak applicationbetiğin baş bölümü değiştirilerek herhangi bir terminal (veya başka bir program için) kullanılabilir :

    #--- set your terminal below
    application = "gnome-terminal"
    #---
  • Yukarıdaki komutlar (tabii ki) bir tür simülasyon için kullanmak istediğinizde komut dosyasından da çalıştırılabilir.
  • Komut dosyası, hem hedeflenen pencere odaklanana hem de komut yazılıncaya kadar bekler, böylece komut her zaman sağ terminal penceresine iner.
  • Komut dosyasının yalnızca komut tarafından çağrılan terminal kurulumu (windows) ile çalıştığını söylemeye gerek yok:

    target_term -set

    Terminal pencereleri, sorunuzda belirttiğiniz gibi komut dosyası tarafından "etiketlenecektir".

  • Yeni bir target_termoturum başlatırsanız , komut dosyası tarafından oluşturulan gizli dosyanın üzerine yazılır, aksi takdirde oturumun kaldırılmasına gerek yoktur.

Güzel, teşekkürler! Ayrıca, python 3.x'in de bu komut dosyasının çalışması için bir gereklilik olduğuna dikkat edilmelidir.
1919'da pompalini
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.