Monday, April 20, 2015

windows 7 - Start program, wait until it outputs certain string, then continue



I want my batch script to run a batch script, which doesn't terminate, then run several more batch scripts, which do terminate, and then close the first batch script.



The issue is, the first batch script I start needs to establish a connection before I can start running the others, and to determine when that's done I need to watch the output of the first script I start for the string that indicates that the connection is established.



In pseudo-code,



start first script
wait for first script to output specific string

while the first script remains running:
run several other scripts
close the first script


This string will appear only after several previous lines have been printed. Both the number of lines and the time this takes can vary. The strings are not outputted all at once. I cannot modify this script.



The desired result is this:



C:\>first_batch_script.bat

Some line
Doing a thing
Winning the points
The Sims did this joke better
Connection established
certain string
C:\>other_batch_script.bat
other_batch_script is done!
C:\>another_batch_script.bat
another_batch_script is done!

C:\>REM kill first_batch_script.bat


This is the code I'm trying:



FOR /f "tokens=* delims=" %%L IN ('first_batch_script.bat ^| find "certain string"') DO echo %%L
call other_batch_script.bat
call another_base_script.bat
REM kill first_batch_script.bat



Using FOR /f seems promising, but when I run this the batch script runs quite slowly and then seems to hang. In any event, even if it ran through, I'm not seeing a good way to then break out of the loop and continue executing my code



Using START /WAIT doesn't help because the first script I start doesn't (and shouldn't) terminate. Using any kind of timing method just won't work because it can take fairly different amounts of time for the connection to be established.



So, long and short:



How do I monitor the output of a batch script, and only execute additional scripts once a certain string has been seen?


Answer



If I understood your requirement correctly, then for /f will not work as it waits till inner process ends. You could try to synchronize on the file, like in this example:
(this would be your depended scripts file, say wait.bat) :




@echo off

:loop
timeout /t 1
(type res.txt |find "trip") > nul 2>&1
if errorlevel 1 goto loop
echo I can go!



start it in cmd window, then open second cmd (same dir) and run (again, as an example):
ping localhost |find "trip" >res.txt
You should see 'I can go' only after ping outputs 'trip' (yes it quits shortly after, but your main script/process does not need to)



Please also note that normally you would start your main script first! This also ensures that the synchro file gets emptied.



You have not said what exactly you need to wait for - maybe there is a more straightforward way of checking that? (eg. using netstat to check open connections)?


No comments:

Post a Comment

linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...