Làm thế nào tôi có thể gửi lệnh đến các cửa sổ đầu cuối cụ thể?


13


Tôi muốn viết một kịch bản để mở nhiều chương trình (máy chủ) đồng thời trong các thiết bị đầu cuối riêng biệt - không quan trọng là cái nào - và gán các lệnh khác nhau cho các thiết bị đầu cuối khác nhau với các lệnh "hạ cánh" bên trong thiết bị đầu cuối chính xác. Điều này có thể không?
Có lẽ, một cái gì đó như thế này:

  1. mở terminal1
  2. mở terminal2 // đồng thời với 1.
  3. lệnh1 // thực thi trong terminal1 mà không cần mở cửa sổ terminal mới
  4. lệnh2 // thực thi trong terminal2 mà không cần mở cửa sổ terminal mới
  5. ...

Tôi bằng cách nào đó có thể gắn nhãn các cửa sổ đầu cuối để các lệnh được thực thi bên trong thiết bị đầu cuối chính xác?

Tôi cũng muốn xem tất cả các thiết bị đầu cuối trong khi các chương trình của chúng đang chạy - các chương trình của tôi có một đối số để in theo dõi / gỡ lỗi cho thiết bị đầu cuối. Vì vậy, tôi muốn xem những thông điệp được trao đổi giữa chúng.

LƯU Ý: Tôi ít quan tâm đến bảo mật dữ liệu trao đổi vì tập lệnh này sẽ đóng vai trò là "mô phỏng". Tôi đã cấu hình mỗi máy chủ để chạy từ một cổng được phân bổ trên localhost.


Kiểm tra pssh ....
heemayl

Làm thế nào chính xác thời gian nên được; một sà lan giả sử 2 giây (mỗi thiết bị đầu cuối) có phù hợp không?
Jacob Vlijm

@JacobVlijm: điều quan trọng hơn đối với tôi là gán các lệnh chính xác theo "cửa sổ" của thiết bị đầu cuối
Aliakbar Ahmadi

1
Có thể được thực hiện, đặc biệt là khi nói về mô phỏng, sẽ đăng lại :)
Jacob Vlijm

1
@JacomVlijm: thực sự câu hỏi của tôi đã được giải quyết một cách ngẫu nhiên: để gửi một lệnh đến đúng thể hiện của nó, mỗi lệnh phải được bắt đầu bằng datadir mà phiên bản đó bắt đầu! Nhưng đối với may mắn của tôi, điều này được thực hiện bằng bitcoin nhưng tôi sẽ chỉ để lại câu hỏi chưa được trả lời .. có lẽ ai đó nghĩ ra một ý tưởng chung hơn cho bất kỳ chương trình nào!? :) Nhưng dù sao cũng cảm ơn!
Aliakbar Ahmadi

Câu trả lời:


14

Vì bạn đề cập bạn đã giải quyết vấn đề cho tình huống cụ thể của mình, bên dưới một giải pháp cho mục đích chung. Nhờ xdotool's --synclựa chọn, nó hoạt động khá đáng tin cậy trong các bài kiểm tra tôi chạy; Tôi có thể "gửi" các lệnh đến các cửa sổ đầu cuối cụ thể và nó chạy hoàn hảo mà không có ngoại lệ.

Làm thế nào nó hoạt động trong thực tế

Giải pháp tồn tại từ một tập lệnh, có thể được chạy với hai tùy chọn -set-run:

  1. Để thiết lập (mở) số lượng cửa sổ đầu cuối tùy ý, trong ví dụ 3 này:

    target_term -set 3

    Ba thiết bị đầu cuối mới sẽ mở ra, id cửa sổ của chúng được ghi nhớ trong một tệp ẩn:

    nhập mô tả hình ảnh ở đây

    Vì lý do rõ ràng, tôi thu nhỏ cửa sổ terminal, tôi chạy lệnh từ :)

  2. Bây giờ tôi đã tạo ba cửa sổ, tôi có thể gửi lệnh đến một trong số chúng bằng lệnh run (vd):

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

    Như được hiển thị bên dưới, lệnh chạy trong thiết bị đầu cuối thứ hai:

    nhập mô tả hình ảnh ở đây

    Sau đó, tôi có thể gửi lệnh đến thiết bị đầu cuối đầu tiên:

     target_term -run 1 sudo apt-get update

    tỉ số giờ sudo apt-get updatechạy trong terminal 1:

    nhập mô tả hình ảnh ở đây

    và như thế...

Làm thế nào để thiết lập

  1. Kịch bản cần cả hai wmctrlxdotool:

    sudo apt-get install wmctrl xdotool
  2. Sao chép tập lệnh bên dưới vào một tệp trống, an toàn dưới dạng target_term(không có phần mở rộng!) Trong ~/bin(tạo thư mục ~/binnếu cần.

  3. Làm cho tập lệnh có thể thực thi được (đừng quên) và đăng xuất / đăng nhập hoặc chạy:

    source ~/.profile
  4. Bây giờ hãy thiết lập các cửa sổ đầu cuối của bạn, với số lượng cửa sổ cần thiết làm đối số:

    target_term -set <number_of_windows>
  5. Bây giờ bạn có thể "gửi" các lệnh đến một trong các thiết bị đầu cuối của mình bằng lệnh:

    target_term -run <terminal_number> <command_to_run>

Kịch bản

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

Ghi chú

  • Tập lệnh được đặt cho gnome-terminal, nhưng có thể được sử dụng cho bất kỳ thiết bị đầu cuối nào (hoặc chương trình khác) bằng cách thay đổi applicationphần đầu của tập lệnh:

    #--- set your terminal below
    application = "gnome-terminal"
    #---
  • Tất nhiên, các lệnh trên có thể được chạy từ một tập lệnh trong trường hợp bạn không muốn sử dụng nó cho một loại mô phỏng nào đó.
  • Kịch bản chờ cho đến khi cả hai cửa sổ được nhắm mục tiêu tập trung và lệnh được gõ xong, vì vậy lệnh sẽ luôn hạ cánh trong cửa sổ đầu cuối bên phải.
  • Không cần phải nói rằng tập lệnh chỉ hoạt động với thiết lập đầu cuối (windows) được gọi bởi lệnh:

    target_term -set

    Các cửa sổ đầu cuối sau đó sẽ được "dán nhãn" bởi tập lệnh, như bạn đề cập trong câu hỏi của mình.

  • Trong trường hợp bạn bắt đầu một target_termphiên mới , tệp ẩn, được tạo bởi tập lệnh sẽ chỉ bị ghi đè, do đó không cần phải xóa nó đi.

Đẹp một, cảm ơn! Cũng cần lưu ý rằng python 3.x cũng là một yêu cầu để kịch bản này hoạt động.
pompalini
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.