【问题标题】:Open terminal, run command, return to SAME terminal later and execute another command打开终端,运行命令,稍后返回 SAME 终端并执行另一个命令
【发布时间】:2018-06-11 17:03:52
【问题描述】:

*请注意,我正在尝试通过脚本自动完成所有操作。显然我可以很容易地手动完成。

编辑

在更好地理解了这个问题之后,我可以更好地提出这个问题。我正在尝试将命令写入给定终端的标准输入。它们需要被接受并作为该终端中的命令运行。

我需要做什么:

我需要从 shell 脚本打开一个终端。我们将其称为终端 1。我需要从终端 1 运行命令。

然后,我需要打开第二个终端(终端 2)并运行第二个命令并等待该命令运行完成。

现在的问题是,我如何返回 到终端 1 并从该终端执行另一个命令? (然后我需要返回终端 2 并执行另一个命令,但这应该是与答案相同的过程)。

必须有某种方法在实例化时为终端实例保留进程 ID

gnome-terminal -e *command* <something to get PID of resulting terminal here?>

我找到的相关答案(没有我想要的所有答案):

免责声明

我已经使用 Linux 很长一段时间了,并且很喜欢在终端上工作。然而,这是我以前从未尝试过的事情。如果我只是错过了有关终端如何运行的基本知识,请指出必要资源的方向以加快速度。

【问题讨论】:

  • 你能解释一下为什么这是你的目标吗?根据我的经验,这不是一个常见的需求,并且有可能(很可能)在没有这种方法的情况下还有其他东西可以实现您的目标。
  • @jeremysprofile,我在虚拟机上运行了一个大型模拟。部分软件在容器中运行。为了初始化和运行,您必须手动在 docker 容器和 VM 之间来回切换并运行命令。我正在尝试自动化这个过程。虽然我应该能够在没有回答这个问题的情况下让它工作,但我相信答案会让它更简单、更干净
  • 有趣。不确定。您可以通过在后台运行它来获取 gnome-terminal 的 PID(在命令后放置 &amp;),然后 var=$! 将让 var 保存 gnome-terminal 进程的 pid。然后你可以wait $var 等等。不确定这是否有帮助。也不确定 gnome-terminals 如何帮助您在容器及其主机之间来回切换。如果这还不够,您能否提供有关如何在主机和容器中运行终端的更多详细信息?
  • @jeremysprofile。这很有帮助,我不知道 var=$!诡计。关于 gnome-terminal,我真的想回到已经打开容器的终端 1 并让它更改目录并执行脚本。我意识到您可以从不同的终端重新登录到容器。这可能是这里的解决方案。
  • @jeremysprofile,我刚刚发现这几乎完全完成了我最初尝试做的事情,我很可能会将它作为这篇文章的答案。需要注意的是,就执行命令而不仅仅是显示文本而言,我还没有让它表现得完全符合我的预期,但我认为它应该可以工作:serverfault.com/a/178470

标签: linux bash


【解决方案1】:

为了从另一个程序或终端向终端写入命令,您必须使用系统输入输出控制系统调用 (ioctl)。 (这可能并非总是如此,但这是我找到的解决方案)。我还将介绍 Python 中的解决方案,但我引用了其他资源,包括下面的 c 中的方法。

首先,您需要您希望向其发送命令的终端实例的进程标识符 (PID) 以使其执行。这可以通过几种方式确定,但我发现最简单的方法是通过以下命令:

ps -A | grep bash --color=always

这将输出打开的终端列表及其 PID 和 pts 编号。我发现知道哪个是您想要的最简单的方法是通过您的程序打开一个终端,运行上述命令,最近打开的终端将是列表中的最后一个。如果你需要确定的话,我相信你可以对它更感兴趣,但这不是这个问题的重点。你会看到类似这样的东西,其中 pts/# 是你所追求的

108514 pts/2    00:00:00 bash

接下来使用以下代码并将其简单地保存到您选择的 .py 文件中(此代码的功劳来自下面第一个链接中的答案,即 Python 链接)。请注意,下面的示例经过硬编码以发送“ls”命令。同样,根据您自己的偏好和用例,更改硬编码命令或使其不进行硬编码。

import fcntl
import sys
import termios

with open(sys.argv[1], 'w') as fd:
    for c in "ls\n":
        fcntl.ioctl(fd, termios.TIOCSTI, c)

然后,只需调用新函数并根据之前找到的 pts 编号将以下路径传递给它,如下所示:

python <your_fcn_name_here).py /dev/pts/#

在 Ubuntu 14.04 上运行良好。我很快就会在 CentOS 上试用它。无需安装任何 python 库即可。

其他资源

这个问题在这里提出的不同:

有关 IOCTL 的更多信息:

【讨论】:

    【解决方案2】:

    在 sh 脚本的最后,添加

    exec $SHELL
    

    类似的问题: https://askubuntu.com/questions/20330/how-to-run-a-script-without-closing-the-terminal

    【讨论】:

      最近更新 更多