Reputation: 399
I am running a batch file through java code. My batch file consists of several commands. i want this process to terminate only after the execution of all the processes. my java code is
String command = "cmd /c start /wait C:\\python27\\tutorial\\check.bat "+key+" "+formattedDate;
Process p=Runtime.getRuntime().exec(command);
p.waitFor();
There are some function after this which i want to execute after all the processes in my batch file are completed. My batch file has
cd\
cd python27
cd tutorial
start scrapy crawl flipkart -a key="%1" -o %2flipkart.xml
start scrapy crawl myntra -a key="%1" -o %2myntra.xml
start scrapy crawl jabong -a key="%1" -o %2jabong.xml
start scrapy crawl hs18 -a key="%1" -o %2hs18.xml
start scrapy crawl indiatimes -a key="%1" -o %2indiatimes.xml
start scrapy crawl shopclues -a key="%1" -o %2shopclues.xml
start scrapy crawl croma -a key="%1" -o %2croma.xml
start scrapy crawl amazon -a key="%1" -o %2amazon.xml
exit
Due to this exit command the batch file is returning back and the main thread continues. I want this batch file to exit only after all the processes are completed. Any help is appreciated.
Upvotes: 0
Views: 2961
Reputation: 130819
I execute each command via cmd.exe so that I can redirect an unused file handle to a lock file. The process holds an exclusive lock on the file until it completes. The file cannot be deleted until the lock is released (the process ends)
I have a loop that attempts to delete the lock files. If a deletion fails, then the process must still be alive so it loops back to try again. I use TIMEOUT to introduce a delay so that the deletion loop does not swamp the CPU.
@echo off
setlocal
cd \python27\tutorial
set "jobs=flipkart myntra jabong hs18 indiatimes shopclues croma amazon"
for %%A in (%jobs%) do start cmd /c scrapy crawl %%A -a key="%1" -o "%~2%%A.xml" 9^>%%A.lock
:waitForCompletion
timeout /t 1 nobreak >nul
for %%A in (%jobs%) do (
del %%A.lock >nul 2>nul
if exist %%A.lock goto :waitForCompletion
)
exit
There is probably no need to see any output in your console windows, so you could use START /B to run each process within the same console, and redirect stdout to nul to hide the output. I left stderr as is just in case an error pops up.
@echo off
setlocal
cd \python27\tutorial
set "jobs=flipkart myntra jabong hs18 indiatimes shopclues croma amazon"
for %%A in (%jobs%) do start /b cmd /c scrapy crawl %%A -a key="%1" -o "%~2%%A.xml" ^>nul 9^>%%A.lock
:waitForCompletion
timeout /t 1 nobreak >nul
for %%A in (%jobs%) do (
del %%A.lock >nul 2>nul
if exist %%A.lock goto :waitForCompletion
)
exit
Upvotes: 0
Reputation: 24466
Did you intend to set all the scrapy
threads to launch asynchronously? If not, simply remove the start
from each line to accomplish your goal.
If the non-blocking threads were intentional, then I'm guessing the threads will probably complete after unpredictable durations, and scrapy crawl amazon
might not necessarily be the last thread to finish.
You could add a loop to your batch script just above exit
to check whether scrapy
exists in the process list -- something like this:
cd \python27\tutorial
start scrapy crawl flipkart -a key="%1" -o %2flipkart.xml
start scrapy crawl myntra -a key="%1" -o %2myntra.xml
start scrapy crawl jabong -a key="%1" -o %2jabong.xml
start scrapy crawl hs18 -a key="%1" -o %2hs18.xml
start scrapy crawl indiatimes -a key="%1" -o %2indiatimes.xml
start scrapy crawl shopclues -a key="%1" -o %2shopclues.xml
start scrapy crawl croma -a key="%1" -o %2croma.xml
scrapy crawl amazon -a key="%1" -o %2amazon.xml
echo Waiting for other threads to complete...
:wait
>NUL 2>NUL (
timeout /t 1 /nobreak || ping -n 2 localhost
tasklist /fi "imagename eq scrapy.exe" | find /i "scrapy" && goto wait
)
exit
Upvotes: 1