1

Edit: I have updated my question and code.

I am running a python script (on hundreds of files) from a batch file. Problem is, python script on some files takes a lot of time to run. What I want is that my python script should not run for more than 5 minutes on a single file. If it takes more than 5 minutes, I would simply want to kill my running script and move to the next file as written in my batch file code below.

What I want is, to define 300 seconds as the maximum time my code can spend on one file. If it takes more than 300 sec, batch file should kill it. However, when it takes less than 300 sec, it should not wait for 300 sec, rather should move to the next statement immediately.

@echo off
setlocal enableextensions disabledelayedexpansion

echo FILE NO: 1
rem filename1 is not a variable name but the name of the file itself
start "Python" python "Code.py" filename1 var1 & call :timeoutProcess "python.exe" 300
start "Python" python "Code.py" filename1 var2 & call :timeoutProcess "python.exe" 300
echo FILE NO: 2
start "Python" python "Code.py" filename2 var1 & call :timeoutProcess "python.exe" 300
start "Python" python "Code.py" filename2 var2 & call :timeoutProcess "python.exe" 300
echo FILE NO: 3
start "Python" python "Code.py" filename3 var1 & call :timeoutProcess "python.exe" 300
start "Python" python "Code.py" filename3 var2 & call :timeoutProcess "python.exe" 300
echo FILE NO: 4
start "Python" python "Code.py" filename4 var1 & call :timeoutProcess "python.exe" 300
start "Python" python "Code.py" filename4 var2 & call :timeoutProcess "python.exe" 300
echo FILE NO: 5
start "Python" python "Code.py" filename5 var1 & call :timeoutProcess "python.exe" 300
start "Python" python "Code.py" filename5 var2 & call :timeoutProcess "python.exe" 300
.
.
.
.
.
.
.
echo FILE NO: 200
start "Python" python "Code.py" filename200 var1 & call :timeoutProcess "python.exe" 300
start "Python" python "Code.py" filename200 var2 & call :timeoutProcess "python.exe" 300

exit /b

:timeoutProcess process timeout [leave]
rem process = name of process to monitor
rem timeout = timeout in seconds to wait for process to end
rem leave   = 1 if process should not be killed on timeout
for /l %%t in (1 1 %~2) do ( 
    timeout /t 1 >nul
    tasklist | find /i "%~1" >nul || exit /b 0
)
if not "%~3"=="1" taskkill /f /im "%~1" >nul
exit /b 1

This code perfectly works fine if I run it till filename5. However, when I ran it upto filename200, this code only runs for filename1 and straightaway moves to filename13 and then filename170. I am not able to understand this issue. There does not seem to be any syntax error.

I am new to writing batch files. Kindly help in solving this issue. If you have any better alternative to solve this problem (instead of timeout), then please do let me know.

P.S.: I also tried to use Timeout function in Python from Eventlet package but this function does not work properly on my files and therefore I thought I should try timeout from batch file instead. I am working on Windows machine and using Python 2.7.

Ankit
  • 11
  • 6

1 Answers1

1

Maybe the easiest way is to loop checking if the process has ended. If the process ends, leave the loop. If the loop ends, kill the process

@echo off
    setlocal enableextensions disabledelayedexpansion

    start "" python "E:\Code1.py"
    call :timeoutProcess "python.exe" 300

    start "" python "E:\Code2.py"
    call :timeoutProcess "python.exe" 300

    exit /b

:timeoutProcess process timeout [leave]
    rem process = name of process to monitor
    rem timeout = timeout in seconds to wait for process to end
    rem leave   = 1 if process should not be killed on timeout
    for /l %%t in (1 1 %~2) do (
        timeout /t 1 >nul
        tasklist | find /i "%~1" >nul || exit /b 0
    )
    if not "%~3"=="1" taskkill /f /im "%~1" >nul 2>nul
    if %errorlevel% equ 128 ( exit /b 0 ) else ( exit /b 1 )

(code adapted from a previous answer)

Community
  • 1
  • 1
MC ND
  • 69,615
  • 8
  • 84
  • 126
  • @Ankit, i have no python at hand to test, but with other script engines it works. Does it also fail when the `start` and the `call` commands are in separate lines or only with the commands concatenated? – MC ND Sep 16 '14 at 12:15
  • @Ankit, please, include the problematic code in the question or start a new question. Without seeing it, it is difficult to determine the reason of the failure. – MC ND Sep 16 '14 at 17:20
  • @Ankit, as said, i don't have a python environment to test, so, i have tested agains node.js with a random waiting process and 5 seconds timeout. And there is no difference if i use a loop or a batch with 600 lines. For me it works. I've been unable to reproduce your error. But i detected the case where the process ends between the timeout loop and the taskkill. Changed code to handle this case. If you have more information, please post it. I'm really intrigued – MC ND Sep 17 '14 at 07:09
  • Thanks for your reply. I am still getting the same error. I have noticed that when I run my batch file. I get 3 cmd window which are running File No: 1, 13 and 170 respectively. I am just wondering how this is possible. File No: 2 should only run when File No: 1 is over and so on. Surprisingly, everytime I run my batch script, it always runs File No: 1, 13 and then starting from 170 to 200 (one by one). But why it does not wait for one file to finish before starting another file> – Ankit Sep 17 '14 at 07:31
  • It also throws some weird error only on some files : "the system can not find batch label specified- timeoutProcess". Confusing thing is, it only throws for some files. – Ankit Sep 17 '14 at 07:35
  • @Ankit, can you post (in pastebin.com or similar) the real content of your batch file? – MC ND Sep 17 '14 at 07:46
  • I think problem is coming because of length of the filename which was given as an input to my python script. I have renamed all of my files and it works much better. Still batch file is not giving me results what I think my script should do. My guess is that in the call statement, either "python.exe" is too long for my batch file to be passed as parameters or character containing (.) can not be passed. What do you suggest to solve this problem? – Ankit Sep 17 '14 at 14:53
  • @Ankit, in batch files the max line length is 8190 chars. The normal limit for file path+name is 256 chars. If i have to bet it is a problem with the characters in filenames or the "variable". Have you tried to quote the file name and the var? – MC ND Sep 17 '14 at 17:29
  • My filename had 27 characters including extension. I had to rename them to have only 6 characters and remove extension as well. Now batch script runs sequqntially very well. However, in few cases (1-2), I got one error saying that the system can not findbatch label specified "python.exe". FYI, I also had to rename ":timeoutProcess" to ":test", otherwise I was getting some error saying that the system can not findbatch label specified "cess". – Ankit Sep 17 '14 at 17:34
  • Yes, I had put quotation mark and sill my script was not working.I had to then rename my input files and then remove extension to make it work. Extension is same for all of my file so I changed my Python script accordingly to include file extension. – Ankit Sep 17 '14 at 17:37