特定の端末ウィンドウにコマンドを送信するにはどうすればよいですか?


13


別々の端末で複数のプログラム(サーバー)を同時に開くスクリプトを作成します-どの端末でも構いません-そして、正しい端末内にコマンドを「ランディング」する異なる端末に異なるコマンドを割り当てます。これは可能ですか?
たぶん、このようなもの:

  1. ターミナル1を開く
  2. terminal2 //同時に1を開きます。
  3. command1 //新しいターミナルウィンドウを開かずにterminal1で実行
  4. command2 //新しいターミナルウィンドウを開かずにterminal2で実行
  5. ...

コマンドが正しい端末内で実行されるように、何らかの方法で端末ウィンドウにラベルを付けることはできますか?

また、プログラムの実行中にすべての端末を監視したい-私のプログラムには、端末にトレース/デバッグを出力するための引数があります。だから、私はそれらの間でどのようなメッセージが交換されているかを見たいです。

注:このスクリプトは「シミュレーション」として機能するため、交換データのセキュリティについてはあまり気にしません。localhostの割り当てられたポートから実行するように各サーバーを構成しました。


psshを確認してください....
heemayl

タイミングの正確さ。のマージは2秒(端末ごと)が適切だとしましょうか?
ジェイコブVlijm

@JacobVlijm:それは正しくターミナル「ウィンドウ」に従ってに割り当てるコマンドに、私にとってより重要だ
Aliakbarアーマディ

1
特にシミュレーションに関する場合は、実行できます:)
ジェイコブVlijm

1
@JacomVlijm:実際に私の質問は偶然に解決されました:コマンドを正しいインスタンスに送信するには、各コマンドの前にインスタンスが開始するdatadirを付ける必要があります!しかし、幸運なことに、これはビットコインで実装されていますが、質問には答えないままにしておきます..おそらく、誰かがプログラムのより一般的なアイデアを思い付くでしょう!?:)しかし、ありがとう!
アリアクバルアハマディ

回答:


14

あなたがあなたの特定の状況の問題を解決したと述べたので、一般的な目的のための解決策の下に。xdotool--syncオプションのおかげで、実行したテストでかなり信頼性の高い動作をします。特定のターミナルウィンドウにコマンドを「送信」でき、例外なく完全に実行されました。

実際の仕組み

解決策は2つのオプションが実行できるスクリプトから存在する -set-run

  1. この例3で、任意の数のターミナルウィンドウをセットアップ(開く)するには:

    target_term -set 3

    3つの新しいターミナルが開き、それらのウィンドウIDは隠しファイルに記憶されます。

    ここに画像の説明を入力してください

    明確にするために、端末ウィンドウを最小化してからコマンドを実行しました:)

  2. 3つのウィンドウを作成したので、runコマンド(たとえば)を使用して、いずれかのウィンドウにコマンドを送信できます。

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

    以下に示すように、コマンドは2番目のターミナルで実行されました。

    ここに画像の説明を入力してください

    その後、最初の端末にコマンドを送信できます。

     target_term -run 1 sudo apt-get update

    作りsudo apt-get update、端末1で実行します。

    ここに画像の説明を入力してください

    等々...

設定方法

  1. このスクリプトは、両方を必要とするwmctrlxdotool

    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、スクリプトのheadセクションを変更することにより、任意の端末(または他のプログラム)に使用できます。

    #--- set your terminal below
    application = "gnome-terminal"
    #---
  • 上記のコマンドは(もちろん)何らかのシミュレーションに使用したい場合に備えて、スクリプトからも実行できます。
  • スクリプトは、ターゲットウィンドウにフォーカスがあり、コマンドの入力が完了するまで待機するため、コマンドは常に正しいターミナルウィンドウに表示されます。
  • スクリプトは、コマンドによって呼び出されたターミナルセットアップ(ウィンドウ)でのみ機能することを言う必要はありません。

    target_term -set

    ターミナルウィンドウは、質問で言及したように、スクリプトによって「ラベル付け」されます。

  • 新しいtarget_termセッションを開始する場合、スクリプトによって作成された隠しファイルは単純に上書きされるため、削除する必要はありません。

いいね、ありがとう!python 3.xもこのスクリプトが機能するための要件であることに注意してください。
ポンパリーニ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.