在一个 Windows 命令提示符下按顺序运行多个程序?

发布于 2024-10-07 06:34:26 字数 878 浏览 0 评论 0 原文

我需要一个接一个地运行多个程序,并且每个程序都在控制台窗口中运行。 我希望控制台窗口可见,但会为每个程序创建一个新窗口。这很烦人,因为每个窗口都在另一个窗口关闭的新位置打开,并且在 Eclipse 中工作时会窃取焦点。

这是我使用的初始代码:

def runCommand( self, cmd, instream=None, outstream=None, errstream=None ):
    proc = subprocess.Popen( cmd, stdin=instream, stdout=outstream, stderr=errstream )

    while True:
        retcode = proc.poll()
        if retcode == None:
            if mAbortBuild:
                proc.terminate()
                return False
            else:
                time.sleep(1)
        else:
            if retcode == 0:
                return True
            else:
                return False

在调用 subprocess.Popen 然后调用 proc.stdin.write( b'program.exe\r\n' ) 时,我切换到使用“cmd”打开命令提示符。 这似乎解决了一个命令窗口问题,但现在我无法判断第一个程序何时完成,我可以启动第二个程序。我想在运行第二个程序之前停止并询问第一个程序的日志文件。

关于如何实现这一目标有什么建议吗?是否还有另一种选项可以在我尚未找到的一个窗口中运行程序?

I need to run multiple programs one after the other and they each run in a console window.
I want the console window to be visible, but a new window is created for each program. This is annoying because each window is opened in a new position from where the other is closed and steals focus when working in Eclipse.

This is the initial code I was using:

def runCommand( self, cmd, instream=None, outstream=None, errstream=None ):
    proc = subprocess.Popen( cmd, stdin=instream, stdout=outstream, stderr=errstream )

    while True:
        retcode = proc.poll()
        if retcode == None:
            if mAbortBuild:
                proc.terminate()
                return False
            else:
                time.sleep(1)
        else:
            if retcode == 0:
                return True
            else:
                return False

I switched to opening a command prompt using 'cmd' when calling subprocess.Popen and then calling proc.stdin.write( b'program.exe\r\n' ).
This seems to solve the one command window problem but now I can't tell when the first program is done and I can start the second. I want to stop and interrogate the log file from the first program before running the second program.

Any tips on how I can achieve this? Is there another option for running the programs in one window I haven't found yet?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

君勿笑 2024-10-14 06:34:26

由于您使用的是 Windows,因此您只需创建一个批处理文件,列出您想要运行的每个程序,这些程序将在单个控制台窗口中执行。由于它是一个批处理脚本,您可以执行诸如在其中放入条件语句之类的操作,如示例所示。

import os
import subprocess
import textwrap

# create a batch file with some commands in it
batch_filename = 'commands.bat'
with open(batch_filename, "wt") as batchfile:
    batchfile.write(textwrap.dedent("""
        python hello.py
        if errorlevel 1 (
            @echo non-zero exit code: %errorlevel% - terminating
            exit
        )
        time /t
        date /t
    """))

# execute the batch file as a separate process and echo its output
kwargs = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
              universal_newlines=True)
with subprocess.Popen(batch_filename, **kwargs).stdout as output:
    for line in output:
        print line,

try: os.remove(batch_filename)  # clean up
except os.error: pass

Since you're using Windows, you could just create a batch file listing each program you want to run which will all execute in a single console window. Since it's a batch script you can do things like put conditional statements in it as shown in the example.

import os
import subprocess
import textwrap

# create a batch file with some commands in it
batch_filename = 'commands.bat'
with open(batch_filename, "wt") as batchfile:
    batchfile.write(textwrap.dedent("""
        python hello.py
        if errorlevel 1 (
            @echo non-zero exit code: %errorlevel% - terminating
            exit
        )
        time /t
        date /t
    """))

# execute the batch file as a separate process and echo its output
kwargs = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
              universal_newlines=True)
with subprocess.Popen(batch_filename, **kwargs).stdout as output:
    for line in output:
        print line,

try: os.remove(batch_filename)  # clean up
except os.error: pass
娇柔作态 2024-10-14 06:34:26

在第 17.5.3.1 节中。 subprocess 模块文档中的常量有 subprocess.CREATE_NEW_CONSOLE 常量的>描述

新进程有一个新的控制台,而不是继承其父进程的控制台
控制台(默认)。

正如我们所看到的,默认情况下,新进程继承其父进程的控制台。您观察到多个控制台被打开的原因是您从 Eclipse 内部调用脚本,而 Eclipse 本身没有控制台,因此每个子进程都会创建自己的控制台,因为它没有可以继承的控制台。如果有人想模拟这种行为,只需运行 Python 脚本即可,该脚本使用 pythonw.exe 而不是 python.exe 创建子进程。两者之间的区别在于前者不打开控制台,而后者则打开控制台。

解决方案是使用帮助程序脚本 - 让我们称之为启动器 - 默认情况下,它创建控制台并在子进程中运行程序。这样,每个程序都会从​​其父程序继承同一个控制台 - 启动器。要按顺序运行程序,我们使用 Popen.wait()< /code> 方法。

--- script_run_from_eclipse.py ---

import subprocess
import sys

subprocess.Popen([sys.executable, 'helper.py'])

--- helper.py ---

import subprocess

programs = ['first_program.exe', 'second_program.exe']
for program in programs:
    subprocess.Popen([program]).wait()
    if input('Do you want to continue? (y/n): ').upper() == 'N':
        break

In section 17.5.3.1. Constants in the subprocess module documentation there's description of subprocess.CREATE_NEW_CONSOLE constant:

The new process has a new console, instead of inheriting its parent’s
console (the default).

As we see, by default, new process inherits its parent's console. The reason you observe multiple consoles being opened is the fact that you call your scripts from within Eclipse, which itself does not have console so each subprocess creates its own console as there's no console it could inherit. If someone would like to simulate this behavior it's enough to run Python script which creates subprocesses using pythonw.exe instead of python.exe. The difference between the two is that the former does not open a console whereas the latter does.

The solution is to have helper script — let's call it launcher — which, by default, creates console and runs your programs in subprocesses. This way each program inherits one and the same console from its parent — the launcher. To run programs sequentially we use Popen.wait() method.

--- script_run_from_eclipse.py ---

import subprocess
import sys

subprocess.Popen([sys.executable, 'helper.py'])

--- helper.py ---

import subprocess

programs = ['first_program.exe', 'second_program.exe']
for program in programs:
    subprocess.Popen([program]).wait()
    if input('Do you want to continue? (y/n): ').upper() == 'N':
        break
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文