如何将命令发送到特定的终端窗口?

我想编写一个脚本,用于在不同的终端中同时打开多个程序(服务器) – 无论哪个 – 并且通过命令“登陆”在正确的终端内为不同的终端分配不同的命令。 这可能吗?
也许,这样的事情:

  1. 开放终端1
  2. 打开终端2 //与1同时发生。
  3. command1 //在terminal1中执行而不打开新的终端窗口
  4. command2 //在terminal2中执行而不打开新的终端窗口

我可以以某种方式标记终端窗口,以便在正确的终端内执行命令吗?

我还想在他们的程序运行时观看所有终端 – 我的程序有一个参数用于打印跟踪/调试到终端。 所以我想看看他们之间交换了什么消息。

注意:我不太关心交换数据的安全性,因为这个脚本应该作为“模拟”。 我已将每个服务器配置为从localhost上的已分配端口运行。

既然你提到你解决了你的具体情况的问题,在一般目的的解决方案下面。 感谢xdotool--sync选项,它在我运行的测试中非常可靠; 我可以“发送”命令到特定的终端窗口,它运行完美,没有例外。

它在实践中如何运作

该解决方案存在于一个脚本中,该脚本可以使用两个选项-set-run

  1. 设置 (打开)任意数量的终端窗口,在本例中为3:

     target_term -set 3 

    将打开三个新终端,将其窗口ID记录在一个隐藏文件中:

    在此处输入图像描述

    为清楚起见,我最小化了终端窗口我运行命令:)

  2. 现在我创建了三个窗口,我可以使用run命令向其中一个窗口发送命令(例如):

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

    如下图所示,该命令在第二个终端中运行:

    在此处输入图像描述

    随后,我可以向第一个终端发送命令:

      target_term -run 1 sudo apt-get update 

    在终端1中运行sudo apt-get update

    在此处输入图像描述

    等等…

如何设置

  1. 该脚本需要wmctrlxdotool

     sudo apt-get install wmctrl xdotool 
  2. 将下面的脚本复制到一个空文件中,在~/bin中将其安全为target_term (无扩展名!)(如果需要,创建目录~/bin

  3. 使脚本可执行 (不要忘记)并注销/运行或运行:

     source ~/.profile 
  4. 现在设置终端窗口,将所需窗口的数量作为参数:

     target_term -set  
  5. 现在,您可以使用以下命令将命令“发送”到任一终端:

     target_term -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设置的,但是可以通过更改脚本head部分中的application来用于任何终端(或其他程序):

     #--- set your terminal below application = "gnome-terminal" #--- 
  • 上面的命令(当然)也可以从脚本运行,以防你将它用于某种模拟。
  • 脚本等待,直到目标窗口都具有焦点并且命令完成输入,因此该命令将始终落在正确的终端窗口中。
  • 无需说该脚本仅适用于命令调用的终端设置(窗口):

     target_term -set 

    然后,终端窗口将被脚本“标记”,就像您在问题中提到的那样。

  • 如果你开始一个新的target_term会话,脚本创建的隐藏文件将被覆盖,所以不需要删除它。