मैं विशिष्ट टर्मिनल विंडो पर कमांड कैसे भेज सकता हूं?


13


मैं अलग-अलग टर्मिनलों में एक साथ कई कार्यक्रम (सर्वर) खोलने के लिए एक स्क्रिप्ट लिखना चाहता हूं - कोई फर्क नहीं पड़ता कि कौन सा - और सही टर्मिनल के अंदर "लैंडिंग" के साथ अलग-अलग टर्मिनलों को अलग-अलग कमांड असाइन करें। क्या यह संभव है?
शायद, कुछ इस तरह:

  1. खुला टर्मिनल 1
  2. खुले तौर पर टर्मिनल 1 // साथ में 1।
  3. कमांड 1 // नई टर्मिनल विंडो खोले बिना टर्मिनल 1 में निष्पादित
  4. कमांड 2 // नई टर्मिनल विंडो खोले बिना टर्मिनल 2 में निष्पादित
  5. ...

क्या मैं किसी तरह टर्मिनल विंडो को लेबल कर सकता हूं ताकि सही टर्मिनल के अंदर कमांड निष्पादित हो?

मैं सभी टर्मिनलों को देखना चाहता हूं, जबकि उनके कार्यक्रम चल रहे हैं - मेरे कार्यक्रमों में टर्मिनल के लिए ट्रेस / डिबग प्रिंटिंग के लिए एक तर्क है। इसलिए मैं देखना चाहता हूं कि उनके बीच किन संदेशों का आदान-प्रदान होता है।

ध्यान दें: मैं एक्सचेंज किए गए डेटा की सुरक्षा के बारे में कम चिंतित हूं क्योंकि इस स्क्रिप्ट को "सिमुलेशन" के रूप में काम करना चाहिए। मैंने प्रत्येक सर्वर को लोकलहोस्ट पर आवंटित पोर्ट से चलाने के लिए कॉन्फ़िगर किया है।


Pssh की जाँच करें ....
heemayl

समय कितना सटीक होना चाहिए; क्या हम 2 सेकंड (प्रति टर्मिनल) उचित कहते हैं?
जैकब वलीजम

@JacobVlijm: टर्मिनल "विंडो" के अनुसार सही ढंग से कमांड सौंपना मेरे लिए अधिक महत्वपूर्ण है
अलीकबर अहमदी

1
किया जा सकता है, खासकर जब यह सिमुलेशन के बारे में है, तो वापस पोस्ट करेंगे :)
याकूब Vlijm

1
@JacomVlijm: वास्तव में मेरे सवाल का सरलता से हल किया गया है: अपने सही उदाहरण के लिए एक कमांड भेजने के लिए प्रत्येक कमांड को डेटादिर के साथ उपसर्ग करना चाहिए जो इंस्टेंस शुरू होता है! लेकिन मेरी किस्मत में यह बिटकॉइन में लागू है लेकिन मैं सिर्फ अनुत्तरित प्रश्न छोड़ दूंगा .. शायद कोई भी किसी भी कार्यक्रम के लिए अधिक सामान्य विचार के साथ आता है !? :) लेकिन धन्यवाद हालांकि!
अलीकबर अहमदी

जवाबों:


14

चूंकि आप उल्लेख करते हैं कि आपने सामान्य उद्देश्य के समाधान के लिए, अपनी विशिष्ट स्थिति के लिए समस्या का समाधान किया है। के लिए धन्यवाद xdotoolके --syncविकल्प, यह परीक्षण मैं भागा में बहुत विश्वसनीय काम करता है; मैं विशिष्ट टर्मिनल विंडो पर "कमांड" भेज सकता था और यह बिना किसी अपवाद के पूरी तरह से चलता था।

यह व्यवहार में कैसे काम करता है

समाधान एक स्क्रिप्ट से मौजूद है, जिसे दो विकल्पों के साथ चलाया जा सकता है -setऔर -run:

  1. करने के लिए सेट इस उदाहरण 3 में टर्मिनल खिड़कियों की एक मनमाना संख्या अप (खुला),:

    target_term -set 3

    तीन नए टर्मिनल खुलेंगे, उनकी विंडो आईडी को एक छुपी हुई फ़ाइल में याद किया जाएगा:

    यहाँ छवि विवरण दर्ज करें

    स्पष्टता के कारणों से मैंने टर्मिनल विंडो को छोटा कर दिया जिससे मैंने कमांड चलाया :)

  2. अब जब मैंने तीन विंडो बनाईं, तो मैं रन कमांड के साथ उनमें से किसी एक को कमांड भेज सकता हूं (जैसे):

    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 में रन बनाना :

    यहाँ छवि विवरण दर्ज करें

    और इसी तरह...

स्थापित कैसे करें

  1. स्क्रिप्ट को दोनों की जरूरत है wmctrlऔर xdotool:

    sudo apt-get install wmctrl xdotool
  2. नीचे दी गई स्क्रिप्ट को एक खाली फ़ाइल में कॉपी करें, इसे सुरक्षित रखें target_term(यदि कोई एक्सटेंशन नहीं है!) ~/bin( ~/binयदि आवश्यक हो तो निर्देशिका बनाएं ) ।

  3. स्क्रिप्ट को निष्पादन योग्य बनाएं (भूल न जाएं) और या तो लॉग आउट करें या अंदर चलाएं:

    source ~/.profile
  4. अब अपने टर्मिनल विंडो को एक तर्क के रूप में आवश्यक विंडो की संख्या के साथ सेट करें:

    target_term -set <number_of_windows>
  5. अब आप कमांड के साथ अपने टर्मिनलों में से किसी एक को "भेज" सकते हैं:

    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"
    #---
    
  • ऊपर दिए गए आदेश (निश्चित रूप से) एक स्क्रिप्ट से चलाए जा सकते हैं और साथ ही साथ आप इसे किसी प्रकार के सिमुलेशन के लिए उपयोग करने के लिए lile करेंगे।
  • स्क्रिप्ट तब तक इंतजार करती है जब तक दोनों लक्षित विंडो पर ध्यान केंद्रित नहीं किया जाता है और कमांड टाइपिंग किया जाता है, इसलिए कमांड हमेशा सही टर्मिनल विंडो में लैंड करेगा।
  • यह कहने की ज़रूरत नहीं है कि स्क्रिप्ट केवल टर्मिनल सेटअप (विंडोज़) के साथ काम करती है जिसे कमांड द्वारा बुलाया गया था:

    target_term -set

    टर्मिनल विंडो को स्क्रिप्ट द्वारा "लेबल" किया जाएगा, जैसे कि आप अपने प्रश्न में उल्लेख करते हैं।

  • यदि आप एक नया target_termसत्र शुरू करते हैं , तो स्क्रिप्ट द्वारा बनाई गई छिपी हुई फ़ाइल बस ओवरराइट हो जाएगी, इसलिए इसे अन्यथा हटाने की कोई आवश्यकता नहीं है।

अच्छा लगा, धन्यवाद! यह भी ध्यान दिया जाना चाहिए कि अजगर 3.x भी इस स्क्रिप्ट को काम करने के लिए एक आवश्यकता है।
पोमपालिनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.