【问题标题】:How to create new console sessions in Python and work with them如何在 Python 中创建新的控制台会话并使用它们
【发布时间】:2014-10-08 15:05:00
【问题描述】:

我正在尝试弄清楚如何在 Python 中使用控制台。假设,我有一个 Python2 脚本。这个脚本应该创建 3 个控制台(bash 或任何其他)并为它们提供不同的命令。

例子:

  • 1 号控制台将负责远程登录
  • 用于 ping 的控制台 #2
  • 3 号控制台将负责新的 ssh 访问

到目前为止我发现的是 subprocess 模块。

我可以用这个

import subprocess
term1 = subprocess.Popen(['open', '-a', 'Terminal'])

但我仍然找不到如何向 term1

发送命令

谢谢。

【问题讨论】:

  • @SylvainLeroux Python2。谢谢
  • 如果我理解得很好,这里的关键问题是你想与运行在终端inside的程序进行通信。不是终端本身。
  • @SylvainLeroux 没有。我的问题是我需要与每个终端本身进行通信并读取所有终端的输出。
  • 显然,我不太清楚你的问题。在我看来,terminal(又名 console)只不过是显示窗口并将 I/O 从/到 PTY 路由到某个主机程序的 GUI 程序而已.该主机程序是真正“有用的东西”:它可能是一个 shell(bash、ssh)、一个 ping 命令或任何其他“控制台模式”程序(即:从 stdin 读取,写入stdout)。所以我不太清楚你想说什么 “我需要与每个终端本身进行通信”
  • @SylvainLeroux 在我的特殊情况下,我必须有 3 个控制台。并运行 3 个不同的命令。每个控制台的每个命令。我的问题是在使用“tcprelay --portoffset 10000 873 23”命令运行第一个控制台后,我也无法运行第二个和第三个控制台。我的脚本在不打开新的控制台会话的情况下运行第一个命令本身。这就是为什么我需要为 3 个命令设置 3 个控制台会话

标签: python bash python-2.7 terminal subprocess


【解决方案1】:

我已经在 Linux 上使用 xterm 进行了测试。可能适应MacOS X终端没有太多问题......我希望。

关键思想是从 Python 创建一个匿名管道,然后指示在终端仿真器内运行的 shell 从该管道中读取:

import os
output, input = os.pipe()
term = subprocess.Popen("xterm -e 'bash </dev/fd/{}'".format(output),shell=True)

f = os.fdopen(input,"wt")

# output as much as command as you want. `flush` between them ... to flush data
f.writelines("echo toto\n")
f.flush()

f.close()

在 GUI 终端模拟器上生成该输出:

如果你想读写,你必须打开两个管道——但如果你在一个方向填充管道,请注意死锁:

>>> import os
>>> output1, input1 = os.pipe()
>>> output2, input2 = os.pipe()
>>> term = subprocess.Popen("xterm -e 'bash </dev/fd/{} >/dev/fd/{}'".format(output1,input2),shell=True)
>>> 
>>> fin = os.fdopen(input1,"wt")
>>> fout = os.fdopen(output2,"rt")
>>> 
# FOR EXPERIMENTAL PURPOSE ONLY: SUBJECT TO DEAD-LOCK !!!
>>> fin.writelines("date\n")
>>> fin.flush()
>>> 
>>> print fout.readline()

Thu Aug 14 23:50:15 CEST 2014

>>> 
>>> fin.close()
>>> fout.close()

话虽如此,在该配置中,打开终端的唯一兴趣是在 GUI 显示屏上显示潜在的 stderr 输出。

如果您只需要与底层命令(bash、ping、...)进行通信,那么您实际上并不需要终端,只需连接到相应的子进程标准 I/O,如另一个答案中所述。

【讨论】:

    【解决方案2】:

    如果您希望能够与您的子进程进行通信,最好使用subprocess.popen

    https://docs.python.org/2/library/subprocess.html#subprocess.Popen

    通过这种方式,您可以创建一个标准输入和 stout 来与进程进行通信。如上面的链接所示,您只需将它们添加到 popen 参数:

    subprocess.Popen(args, stdin=PIPE, stdout=PIPE)
    

    还有popen.communicate(input= 'your input')

    这将等待命令完成。

    【讨论】:

    • 这也是我的第一个想法,但我已经在 Linux 上使用 xterm 尝试过,但没有成功。你能确认这适用于 MacOS X Terminal 吗?
    • 您的代码应该类似于: term1 = subprocess.Popen(['open', '-a', 'Terminal'], stdin=PIPE,stdout = PIPE) 这样您就可以使用: return_info = term1.communicate(input="your_input") 它应该给你一个回报。
    猜你喜欢
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    相关资源
    最近更新 更多