循环遍历未终止的批处理脚本

时间:2016-12-07 14:54:13

标签: python windows batch-file subprocess

我试图在python循环中执行几个批处理脚本。但是,所述bat-scripts包含cmd /K,因此不会“终止”(因为缺少更好的单词)。因此python调用第一个脚本并永远等待...

这是一个伪代码,可以让我了解我要做的事情:

import subprocess

params = [MYSCRIPT, os.curdir]    
for level in range(10):
    subprocess.call(params)  

我的问题是:“是否有一个pythonic解决方案可以恢复控制台命令并恢复循环?”

编辑:我现在意识到可以启动子进程并继续而无需等待它们返回,使用

Popen(params,shell=False,stdin=None,stdout=None,stderr=None,close_fds=True)

然而,这将几乎同时启动我的整个循环。有没有办法等待子进程执行其任务,并在它到达cmd /K并返回空闲时返回。

2 个答案:

答案 0 :(得分:3)

没有内置方式,但这是你可以实现的。

示例是使用bash,因为我无法访问Windows计算机,但cmd \K

应该类似

它可能很简单:

import subprocess

# start the process in the background
process = subprocess.Popen(
    ['bash', '-i'],
    stdout=subprocess.PIPE,
    stdin=subprocess.PIPE
)

# will throw IO error if process terminates by this time for some reason
process.stdin.write("exit\n")
process.wait()

这会向shell发送一个exit命令,应该在脚本终止时处理它,导致它退出(有效地取消\K

如果您需要一个检查某些输出的解决方案,这里有一个更详细的答案:

import subprocess

# start the process in the background
process = subprocess.Popen(
    ['bash', '-i'],
    stdout=subprocess.PIPE,
    stdin=subprocess.PIPE
)

    # Wait for the process to terminate
    process.poll()
    while process.returncode is None:
        # read the output from the process
        # note that can't use readlines() here as it would block waiting for the process
        lines = [ x for x in process.stdout.read(5).split("\n") if x]
        if lines:
            # if you want the output to show, you'll have to print it yourself
            print(lines )
            # check for some condition in the output
            if any((":" in x for x in lines)):
                # terminate the process
                process.kill()
                # alternatively could send it some input to have it terminate
                # process.stdin.write("exit\n")
        # Check for new return code
        process.poll()

这里的复杂功能是读取输出,就好像你试图读取超过可用的数量一样,该过程将阻止。

答案 1 :(得分:2)

这是我使用的东西,我开始一堆进程(本例中为2)并在程序终止之前等待它们。可以修改它以在不同时间等待特定进程(请参阅注释)。在此示例中,一个进程打印出%path%,另一个进程打印目录内容。

import win32api, win32con, win32process, win32event

def CreateMyProcess2(cmd):
    ''' create process width no window that runs sdelete with a bunch of arguments'''
    si         = win32process.STARTUPINFO()
    info = win32process.CreateProcess(
        None,      # AppName
        cmd,       # Command line
        None,      # Process Security
        None,      # Thread Security
        0,         # inherit Handles?
        win32process.NORMAL_PRIORITY_CLASS,
        None,      # New environment
        None,      # Current directory
        si)        # startup info
    return info[0]
# info is tuple (hProcess, hThread, processId, threadId)

if __name__ == '__main__' :
    handles       = []

    cmd = 'cmd /c "dir/w"'
    handle = CreateMyProcess2(cmd)
    handles.append(handle)

    cmd = 'cmd /c "path"'
    handle = CreateMyProcess2(cmd)
    handles.append(handle)

    rc = win32event.WaitForMultipleObjects(
        handles, # sequence of objects (here = handles) to wait for
        1,       # wait for them all (use 0 to wait for just one)
        15000)   # timeout in milli-seconds
    print rc
    # rc = 0   if all tasks have completed before the time out  

近似输出(为清晰起见而编辑):

PATH = C:\ Users \ Philip \ algs4 \ java \ bin; C:\ Users \ Philip \ bin; C:\ Users \ Philip \ mksnt \ etc ......

驱动器C中的卷没有标签。 卷序列号为4CA0-FEAD
目录C:\ Users \ Philip \ AppData \ Local \ Temp
[。]
[..]
FXSAPIDebugLogFile.txt
等....
1个文件0个字节
3 Dir(s)305,473,040,384字节免费

0< - “rc”的值