Loop over a script package that does not end

I am trying to execute several batch scripts in a python loop. However, these bat scripts contain cmd /K and thus do not "end" (due to the lack of a better word). Therefore python calls the first script and waits forever ...

Here is the pseudo code that gives an idea of ​​what I'm trying to do:

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

My question is: "Is there a pythonic solution to return the console command and resume the loop?"


EDIT: now I know that you can start child processes and continue without waiting for them to return, using

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

However, this would start the entire cycle almost simultaneously. Is there a way to wait for a child process to complete its task and return when it reaches cmd /K and becomes inactive.

+6
source share
2 answers

There is no built-in way, but this is what you can implement.

Examples are bash, since I do not have access to the Windows machine, but it should be similar for cmd \K

It could be that simple:

 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() 

This will send the exit to the shell, which should be handled the same way the script ends, forcing it to exit (effectively undoing \K )

Here's a more complicated answer if you need a solution that checks some kind of output:

 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() 

The difficulty here is to read the output, as if you were trying to read more than available, the process is blocked.

+3
source

This is what I use when I start a bunch of processes (2 in this example) and wait for them at the end until the program ends. It can be modified to wait for certain processes at different times (see Comments). In this example, one process returns% path% and another prints the contents of the directory.

 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 

Approximate output (edited for clarity):

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

The volume on drive C has no label. Volume Serial Number - 4CA0-FEAD
Directory C: \ Users \ Philip \ AppData \ Local \ Temp
[.]
[..]
FXSAPIDebugLogFile.txt
etc....
1 file 0 bytes
3 Deer 305,473,040,384 bytes for free

0 <- the value of "rc"

+2
source

Source: https://habr.com/ru/post/1012978/


All Articles