【问题标题】:How to resume a terminal with subprocess python如何使用子进程 python 恢复终端
【发布时间】:2021-10-16 22:47:00
【问题描述】:

我正在使用 Python 中的 subprocess 模块。我正在尝试运行一系列终端来自动化流程。

分解它: 我想打开 3 个终端来运行一组命令 像这样:

Terminal 1: `cd src` -> `./run_script.sh`

Terminal 2: cd data -> `python prepare_data.py`

Terminal 3: `cd src` -> `./do_something.sh` #runs some docker container

Terminal 4: `cd src` -> `./do_another.sh`

Terminal 3: `./another_bash.sh`

要自动执行以下操作:

class AutomateProcesses:
    
    def run_terminal_1(self):
        subprocess.call('./run_script.sh', shell=True, cwd='../src')
    
    def run_terminal_2(self):
        subprocess.call('python prepare_data.py', shell=True, cwd='../../data')
    
    def run_terminal_3(self):
        subprocess.call('./do_something.sh.sh', shell=True, cwd='../src')
    
    def run_terminal_4(self):
        subprocess.call('./do_another.sh', shell=True, cwd='../src')
    

如何返回终端 3 运行命令?

【问题讨论】:

  • 你为什么不创建另一个子进程并作为第 5 个命令运行它?
  • 3号航站楼是一个docker容器,需要跑到那里
  • 无论如何——如果你正确使用了 Docker,你告诉它在当你启动容器时运行什么命令。当您希望容器以非交互方式运行命令时,让容器启动一个交互式 shell 是使用 Docker 的一个例子。不要那样做:告诉 Docker 你想让它启动什么,然后让它自己做
  • (另外,在可执行文件的文件名上使用.sh 扩展名并不是很好。如果你想用 Python 重写其中一个脚本会发生什么——你要重命名它们然后需要更改吗?所有的来电者?就像你运行pip而不是pip.py,和ls而不是ls.elf,你的do_another应该被命名为do_another而不是.sh;参见talisman.org/~erlkonig/documents/…关于该主题的文章,或wooledge.org/~greybot/meta/.sh 与相关#bash factoid 的历史以显示历史共识)。
  • 无论如何——如果你真的想要与“终端 3”的标准输入和标准输出进行交互,你需要从 subprocess.call() 切换到 subprocess.Popen() , 并至少设置stdin=PIPE。如果您想观看 stdout 或 stderr,您还需要通过管道将它们分流。

标签: python python-3.x shell terminal subprocess


【解决方案1】:

看起来你想在一个“终端”上运行几个命令(实际上你没有看到任何终端),它只是一个运行 shell 的子进程。

我使用名为 pexpect (https://pexpect.readthedocs.io/en/latest/overview.html) 的工具,它具有 Windows 版本的 wexpect (https://pypi.org/project/wexpect/)。

以下是代码示例,使用子变量,您可以保留“终端”并向其发送命令。

import pexpect
# log file to capture all the commands sent to the shell and their responses
output_file = open('log.txt','wb')

# create the bash shell sub-process
child = pexpect.spawn('/bin/bash', logfile=output_file)
child.stdout = output_file
child.expect(bytes('>', 'utf-8'))
# make sure you use the pair (sendline() and expect()) to wait until the command finishes
child.sendline(bytes('ls', 'utf-8'))
child.expect(bytes('>', 'utf-8'))

child.sendline(bytes('echo Hello World', 'utf-8'))
child.expect(bytes('>', 'utf-8'))

output_file.close()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2013-07-21
    • 2020-07-14
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    相关资源
    最近更新 更多