在特定的终端窗口中执行命令 - Python

3
如何使用Python在特定终端窗口中执行已打开的命令? 我可以使用Python在新终端中执行命令,但我想重用现有的终端。而且有多个终端已经打开。 命令应该在特定的终端中运行。
例如: 1. 我在Terminal1中启动了进程A。 2. 我杀死了进程A。(现在Terminal1处于空闲状态) 3. 我想重新启动进程A并在Terminal1中显示进程A的日志/输出。
我正在使用Ubuntu。
做这件事的原因: - 将特定命令的日志保留在同一终端中。 - 将多个应用程序的日志分别保存到不同的终端中。 - 在相应的终端中维护特定应用程序的日志 (应用程序自动多次被杀死和启动)。

如果你的程序是通过在某种图形界面中双击文件来启动的,那么讨论的起点就是确切地讨论你使用的是哪种图形界面,以及你是否愿意在其中运行可以附加到其中的软件(例如 tmuxscreen)。 - Charles Duffy
(此外,仅需要缓冲输出还是还需要检索输入也是一个重要的区别)。 - Charles Duffy
如果您已经选择的软件已经在终端中运行并附加,那么该软件可以等待一个信号(例如,通过GUI操作或任何其他应该从终端外部触发程序运行的东西)来启动。这也为您提供了其他选择。 - Charles Duffy
重要的是,有很多方法可供选择(其中一些属于首先避免问题的范畴),而这个问题缺乏足够的细节和澄清来建立一个具体的答案的基础。 - Charles Duffy
1
所以,这种问题的一般解决方法是:在终端1中启动不是processA而是processA-viewer。你让processA-viewer不断地追踪processA写入的日志(或者通过套接字通信等方式)。当你运行processA时,processA-viewer会显示它的输出。当你退出processA时,processA-viewer会继续运行,等待新的processA启动。明白了吗?(processA-viewer不需要自己编写--已经有几个可用的工具可以完成这项工作)。 - Charles Duffy
显示剩余10条评论
1个回答

0

我的解决方案有些笨拙,而且存在安全问题。也许其他人可以发布更好的解决方案。

为了在打开的终端窗口中执行命令,我使用了ttyecho(请参见unix.stackexchange上的post)。这种方法的安全问题似乎类似于使用shell=Truesubprocess.Popensubprocess.run

至于选择特定的打开终端,Linux命令ps a列出与tty相关联的进程并标识tty。我正在使用Debian衍生版,因此我的打开终端显示为具有“pts/n”(伪终端从属)tty的进程,其中n是区分不同打开终端实例的整数。例如:

 PID TTY      STAT   TIME COMMAND
 191 tty7     Rsl+   9:12 /usr/lib/xorg/Xorg :0 -seat seat0 -aut /var/run/ligh
1049 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
1050 ttyS0    Ss+    0:00 /sbin/agetty ==keep-baud 115200,38400,9600,ttyS0 vt22
4254 pts/0    Ss     0:00 bash
4675 pts/1    Ss+    0:00 bash
4876 pts/2    Ss+    0:00 sudo /srv/xxx/main.py
4878 pts/2    S+     0:01 python3 /srv/xxx/main.py
5012 pty/0    R+     0:00 ps a

假设您可以通过终端中已经运行的内容区分要在哪个终端中运行命令,您可以使用类似以下 Python 代码的方式:
import subprocess
r = subprocess.run(['ps', 'a'], stdout=subprocess.PIPE, universal_newlines=True)
try:
    pts = [*(line for line in r.stdout.split('\n') if searchstring in line)][0]=.split(' ')[1][4:]
except IndexError:
    pts = None
if pts:
    r2 = subprocess.run(['sudo', 'ttyecho', '-n', '/dev/pts/' + pts, command])

我已经在运行Kali(使用xfce4-terminal)的rPi上使用Python 3.5进行了测试。


顺便说一下,我认为这很相关,因为我还没有花时间学习一个合适的Python GUI,而是使用Unix终端作为多窗口Python GUI的简单代理。 - ucla87
为什么不编辑您之前(已删除的)答案,而是添加第二个答案? - Charles Duffy
顺便问一下,如果不使用sudo而是直接将标准输入和输出附加到tty(直接从Python进程中打开它),那么ttyecho在这里给你什么?(是的,如果程序尝试与/dev/tty交互,那可能会有问题,但大多数软件不会...并且据我所知,看起来OP只是想要记录日志)。 - Charles Duffy
我删除了第一个答案,因为我在输入部分代码时不小心点击了“提交”按钮,而我又不想让任何人在我完成答案之前被不完整的代码所困扰。 - ucla87
顺便说一下,使用终端窗口和ttyecho,您可以在Linux gui中的不同终端窗口中同时查看运行的各个Python进程的输出,并在它们崩溃并需要重新启动时返回查看其输出。因此,更多的调试类型用途--因此建议使用logging模块,它轻松地允许消息同时发送到*终端和日志文件。 - ucla87
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接