Timeout via for loop

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Timeout via for loop

#1 Post by A_Bobby » 31 Oct 2022 14:48

Hi,

Trying to display just "Waiting for n seconds" from a timeout command without the press any key to continue or even press CTRL+C using /nobreak option. Is it possible to use a for loop for that (or any other method)? I tried to parse tokens but the output only displays after the entirety of the timeout command has finished. I want this displayed while the command is running.

I have seen some scripts do that but they were too complex and I need to use this command repeatedly within my script so for simplicity sake, not more than 2 to 3 lines of code.

Thanks

A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Re: Timeout via for loop

#2 Post by A_Bobby » 31 Oct 2022 15:06

So I did the following
for /l %a in (5,-1,1) do @ping -n 2 localhost >nul && @echo Waiting for %a seconds...
and while it does get me what I need, the scrolling format is not acceptable, has to be just one line changing just the second value. This is not entirely accurate second count but my output is something that needs to resemble this.

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Timeout via for loop

#3 Post by aGerman » 31 Oct 2022 15:57

ECHO does always write a new line. You need to use the SET /P trick. However, that's not enough. You also need both a Carriage Return character to jump back to the beginning of the line, and the combination of Backspace-Space-Backspace characters to overwrite the previous last character in the line with a space because the next line may get shorter (e.g. count down from 10 where 10 has two digits, 9 only one).

Code: Select all

@echo off &setlocal
for /f "tokens=1,2 delims=#" %%a in (
  'prompt #$H#^&for /f %%b in ^('copy /z "%~f0" nul'^) do %%b# 2^>nul'
) do (set "del=%%a"&set "cr=%%b")

setlocal EnableDelayedExpansion
for /l %%a in (10,-1,1) do (
  <nul set /p "=%del%!cr!Waiting for %%a seconds ..."
  >nul timeout /t 1 /nobreak
)
echo !cr!Waiting for 0 seconds ...
endlocal

pause
Steffen

A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Re: Timeout via for loop

#4 Post by A_Bobby » 31 Oct 2022 16:51

This is simply awesome!! A little convoluted but awesome nevertheless. As I said originally that I need small 2 to 3 lines of code to do this but with batch, it's not possible so in order to not make my script a hundred's of lines long, I need to run another loop which essentially uses utility called adb.exe to manipulate a TV set top box to automatically change channels while logging is being run in the background to check for any errors in the system. My original script ran something like this

@echo off
setlocal EnableDelayedExpansion
@echo.
cls
@echo.
set /p IPAddress=Enter IP address for STB:
@echo.
set /p Enter the duration for channel change in seconds:
@echo Connecting to the STB with IP %IPAddress%
adb disconnect
adb connect %IPAddress%
if "%errorlevel%" neq "0" exit /b
@echo.
@echo Tuning to channel 1306...
adb shell input keyevent "KEYCODE_1"
timeout /t 1 /nobreak >nul
adb shell input keyevent "KEYCODE_3"
timeout /t 1 /nobreak >nul
adb shell input keyevent "KEYCODE_0"
timeout /t 1 /nobreak >nul
adb shell input keyevent "KEYCODE_6"
@echo Waiting for 1 hour...
timeout /t 3600 /nobreak

The last 2 lines are the ones I was going to replace with your code. But I have to do this test over for over 10 hours so I have like 10 channel changes that happen every hour. I can come up with a for loop to do a simple string of 1306 but to parse individual keycodes with a second of timeout in between is something I can't do. Do you think this is even possible?
Many thanks again Steffen!!

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Timeout via for loop

#5 Post by aGerman » 01 Nov 2022 03:18

Check this out. Just run it, it can't do any harm yet.
Then carefully read the comments in order to understand how to customize it.

Steffen

Code: Select all

@echo off
REM create both Carriage Return, and the combination of Backspace-Space-Backspace once at the beginning of your code
for /f "tokens=1,2 delims=#" %%a in (
  'prompt #$H#^&for /f %%b in ^('copy /z "%~f0" nul'^) do %%b# 2^>nul'
) do (set "del=%%a"&set "cr=%%b")

REM *** do your prompting and connecting stuff here ... ***

REM *** update the below (to end up with a list of successive calls of the subroutine for your about 10 channels) ***
call :tuning_channel 1306
call :tuning_channel 1324
REM etc.

pause

REM always end the main code with this line:
goto :eof

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
REM put this subroutine at the end of the whole script
:tuning_channel
setlocal EnableDelayedExpansion
echo Tuning to channel %~1 ...
REM that funny FOR loop separates the digits in the string an runs the body for each of them
for /f %%i in ('^(cmd /u /c "<nul set /p=%~1"^)^|find /v ""') do (
  REM *** remove the all-caps ECHO, it's only there for debugging reasons since I don't have the adb tool installed ***
  ECHO adb shell input keyevent "KEYCODE_%%i"
  >nul timeout /t 1 /nobreak
)

REM *** begin with 3600 in real world ***
for /l %%a in (10,-1,1) do (
  <nul set /p "=%del%!cr!Waiting for %%a seconds ..."
  >nul timeout /t 1 /nobreak
)
echo !cr!Waiting for 0 seconds ...
endlocal
goto :eof


A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Re: Timeout via for loop

#6 Post by A_Bobby » 02 Nov 2022 16:22

Thanks a lot Steffen for this. This works like a charm. Still trying to wrap my head around these 2 loops
for /f "tokens=1,2 delims=#" %%a in (
'prompt #$H#^&for /f %%b in ^('copy /z "%~f0" nul'^) do %%b# 2^>nul'
) do (set "del=%%a"&set "cr=%%b")

and

for /f %%i in ('^(cmd /u /c "<nul set /p=%~1"^)^|find /v ""')

However, I ran into another issue which I think would be trivial for you. In this script I launch a log capture that runs in the background while all these channel changes are happening. After the subroutine for channels is done, the I kill off log capture. Then I have this errorlist.txt with strings that are known as indicators of something bad going on in the STB and I have to spit them out when I find them. For that I run this

for /f "tokens=1,2 delims=|" %%a in (errorlist.txt) do (
findstr /C:"%a" %cd%\Logs\*.*
if %errorlevel% == 0 goto :errordisplay
)
:errordisplay
@echo Error condition found check logs

But this just parses all strings and resets errorlevel to 1 when the string is not found. So when a string is found, I want the script to spit it out in the output window.
Again, many thanks for your help. I wish you guys had some kind of paypal link to thank you properly. Or you can message me privately and I will be more than happy to buy you lunch :)

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Timeout via for loop

#7 Post by aGerman » 04 Nov 2022 10:31

You have this line:

Code: Select all

findstr /C:"%a" %cd%\Logs\*.*
Doesn't it already display the found string?

Steffen

A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Re: Timeout via for loop

#8 Post by A_Bobby » 08 Nov 2022 16:44

It does but I want it to find all strings it can find in the errorlist.txt and spit them out.

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Timeout via for loop

#9 Post by aGerman » 08 Nov 2022 17:57

OK but what would be the FINDSTR pattern then? As to my understanding you already search all log files that have been created.

Steffen

A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Re: Timeout via for loop

#10 Post by A_Bobby » 09 Nov 2022 08:27

So strings are as follows and do a pipe delimiter to get 1st token

BERR_OUT_OF_SYSTEM_MEMORY | Dynamic heap issue
SAGE specific error | DRM_WVOemCrypto
Failed to allocate omx component 'OMX.bcm.vdec.avc.secure' | H264 encoded streams SD/HD
Failed to allocate omx component 'OMX.bcm.vdec.av1'
Failed to allocate omx component 'OMX.bcm.vdec.vp9'
Failed to allocate omx component 'OMX.bcm.vdec.hevc.secure' | H265 encoded streams 4K
Video HandleSignalLost | Occurs when connection drops
CCExt : Status: -61' | Occurs when close captions fails
IPTV_HAL_Decoder_Decrypt | Decryption issue, either failed or key no aquired
Too many frames in past! Flushing video decoder | High chance of video problems
BERR_OUT_OF_DEVICE_MEMORY | Dynamic heap issue
ERROR! Hasn't enough continuous memory in memoryPool | Our of memory error
isImpairment: 1 | box impaired due to unknown reason

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Timeout via for loop

#11 Post by aGerman » 09 Nov 2022 16:16

I think I understood what you're after.

Code: Select all

set "err="
for /f "delims=|" %%a in (errorlist.txt) do (
  findstr /C:"%a" %cd%\Logs\*.*
  if not errorlevel 1 set "err=1"
)
if defined err goto :errordisplay

A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Re: Timeout via for loop

#12 Post by A_Bobby » 09 Nov 2022 17:54

No, that does not do it. Disabling echo I see the script stuck at
if defined err goto :errordisplay

Sorry if I have not been very clear on this. So the log that is generated (under logs directory) needs to be parsed for each string listed in errorlist.txt. If there is a single string match or a multiple matches, this portion of the script needs to spit out each string found in that log on the screen saying something like found error "string1" and "string2" in the log.

ShadowThief
Expert
Posts: 1160
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Timeout via for loop

#13 Post by ShadowThief » 09 Nov 2022 20:19

Did you only want the "BERR_OUT_OF_SYSTEM_MEMORY" bit instead of the full line?

A_Bobby
Posts: 38
Joined: 21 Oct 2010 12:48

Re: Timeout via for loop

#14 Post by A_Bobby » 10 Nov 2022 05:40

Yes, any/all strings before the pipe (and minus one space before the pipe) needs to be spat out in the script.

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Timeout via for loop

#15 Post by aGerman » 11 Nov 2022 10:39

Disabling echo I see the script stuck at
if defined err goto :errordisplay
Huh? Provided that the :errordisplay label exists, this shouldn't ever have happened.

Code: Select all

set "err="
for /f "delims=|" %%a in (errorlist.txt) do (
  for /f "delims=|" %%b in (''2^>nul findstr /C:"%a" "%cd%\Logs\*.*"') do (
    set "err=1"
    set "str=%%b"
    setlocal EnableDelayedExpansion
    echo !str:~0,-1!
    endlocal
  )
)
if defined err goto :errordisplay

Post Reply