Diagnostics or other optional tests

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Diagnostics or other optional tests

Post by MigrationUser »

18 Jul 2007 20:13
avery_larry


Anyone have any creative ways to program something like a debug mode or other options in a looping batch file? The only thing I've come up with is something like setting a variable someplace and then adding a bunch of if statements:

Code: Select all

set collectstats=1
set debug=0
set optionalextratest=0

:loop
if %debug%==1 echo on
<normal code here>
if %debug%==1 pause
if %collectstats%==1 (
   do something like increment a counter for this particular loop
)
<more code here>
if %debug%==on pause
if %collectstats%==1 (
   collect more stats at this point in the loop
)
<more code>
if %debug%==1 pause
if %optionalextratest%==1 (
   run the optional test
   if %debug%==1 pause
   if %collectstats%==1 (
      collect stats on the optional extra test here
   )
)
goto loop
The problem I have with this is that the application I have in mind is a looping batch script and I'm trying to optimize it. Putting aside the annoyance of all that extra code, I don't like the idea of adding so many if statements that will evaluate over and over and over. This code will loop through as many as 30 times per minute.

The other idea that's trying to form in my mind is using the variable with a goto statment like this somehow:
set collectstats=1
set debug=0
set optionalextratest=0

goto loop%collectstats%

:loop0
<code for the loop with no stats.
goto loop%collectstats%

:loop1
<code for the loop with stats.
goto loop%collectstats%
But then I don't like redundant code -- not to mention the extra work making sure any changes that I make are changed in multiple locations.

----------------------------

#2 20 Jul 2007 13:34
bluesxman


First of all, as a general rule I'd recommend not using "goto"; try to use the "call :label" syntax whereever possible instead. The main advantages are that you can pass parameters to a "called" procedure, and at the end use "goto :EOF" to effortlessly return from whence you came. You can even use "exit /b" to return a proper errorlevel value, should you wish.

Back to your question...

If I need to put some debugging in that I'll be using frequently during the script's development, I tend to take advantage of the ability to use self-modifying code in CMD.

Here's a simple example of the sort of things I do (untested):

Code: Select all

@echo off

set debug=0
if /i "%~1" EQU "/debug" set debug=1

if "%debug%" EQU "1" (
    set db1=
    set db2=echo:
    set nul=con
) ELSE (
    set db1=REM
    set db2=
    set nul=nul
)

%db1%    echo:** Find command output START **
    type somefile.txt | find "some text" 1>%nul% 2>&1
%db1%    echo:** Find command output END **

%db1%    type somefile.txt
%db1%    echo:%errorlevel%
    if %errorlevel% EQU 0 (
        echo:"some text" was found, deleting somefile.txt
%db2%        del somefile.txt    
    ) ELSE (
        echo:"some text" was not found
%db2%        call somescript.cmd
    )

%db1%    pause

goto :EOF
In this manner, you can save cluttering up your script with a lot of "if" statements.

Here's another example, along the same lines but with a different implementation, that I've cribbed directly from a script I wrote recently:

Code: Select all

set pause=
cls=cls
set flags=a m r f d

for %%x in (%flags%) do set _%%x=

if "%_testmode%" EQU "1" (
    echo:Running in test mode.
    echo:
    echo:Available test flags: [a]ge logs [m]ove [r]ar [f]tp [d]elete
    set /p "flags=Please choose your flags (actions will NOT take place) [%flags%]: "
    echo:
    title %name%_v%version% [Dev Flags: !flags!]
    for %%a in (!flags!) do set _%%a=echo:
    set pause=pause
    set cls=
)
What I then did, further down the script, was prepend (for example) the "ftp" commands with "%_f%", such that they'd be echoed rather than run. There were also numerous "%pause%" and "%cls%" lines at key points throughout.

Last edited by bluesxman (20 Jul 2007 13:36)

cmd | *sh | ruby | chef

----------------------------

#3 20 Jul 2007 15:54
daat99


bluesxman, your post is great help to everybody, thank you very much for it smile

Can you please show a working example of the second method you described there?
I'm not sure I fully understand how you're using it and what's going on in there sad

Thanks in advanced
daat99

Last edited by daat99 (20 Jul 2007 15:54)

I always try to help wink
Sometimes I don't know how sad

----------------------------

#4 20 Jul 2007 16:53
bluesxman


Hopefully this'll make it a bit clearer (untested):

Code: Select all

@echo off

setlocal enabledelayedexpansion

set _testmode=0
if "%~1" NEQ "" set _testmode=1

set pause=
set cls=cls
set flags=a m r f d

for %%x in (%flags%) do set _%%x=

if "%_testmode%" EQU "1" (
    echo:Running in test mode.
    echo:
    echo:Available test flags: [a]ge logs [m]ove [r]ar [f]tp [d]elete
    set /p "flags=Please choose your flags (actions will NOT take place) [%flags%]: "
    echo:
    title %name%_v%version% [Dev Flags: !flags!]
    for %%a in (!flags!) do set _%%a=echo:
    set pause=pause
    set cls=
)

REM set up your script variables AFTER the above to prevent the user messing up something by mistake.

%pause%
%cls%
echo:Age files...
%_a% REM I'd be a command which is part of a log aging process, normally you wouldn't see me
ping 127.0.0.1 >nul
%pause%
%cls%
echo:Move files...
%_m% REM I'd be a command to move some files, normally you wouldn't see me
ping 127.0.0.1 >nul
%pause%
%cls%
echo:RAR files...
%_r% REM I'd be a command to create a RAR archive, normally you wouldn't see me
ping 127.0.0.1 >nul
%pause%
%cls%
echo:FTP files...
%_f% REM I'd be a command to launch an FTP session, normally you wouldn't see me
ping 127.0.0.1 >nul
%pause%
%cls%
echo:Delete files...
%_d% REM I'd be a command to delete some files, normally you wouldn't see me

%pause%

ping 127.0.0.1 >nul
In this example, if you start the script without any command line input the variable "_testmode" is set to 0 and the variables _a _m _r _f _d will all be empty, thus they do not affect the commands they are prepended before.

If you start the script with any value as the command line input, "_testmode" is set to 1 and you get the choice of disabling certain functionality in the script. In "testmode", by default all functions are disabled (the commands are echoed instead of being processed). If you specify less than the default flags, only those specified functions will be disabled. The functionality is disabled because the script sets up the chosen variables (_a _m _r _f _d) with a value of "echo:", thus the commands they prepend will be output to screen rather than being run. Entering a space at the flags will cause it to run as normal, but with "cls" disabled and a "pause" at every stage.

Last edited by bluesxman (23 Jul 2007 10:16)

cmd | *sh | ruby | chef

----------------------------

#5 22 Jul 2007 06:46
daat99


bluesxman, that's a very helpful post once again, thanks a lot.
I certainly learn a lot just from reading your replies smile

I always try to help wink
Sometimes I don't know how sad

----------------------------

#6 22 Jul 2007 21:49
bluesxman


np, glad to help

cmd | *sh | ruby | chef

----------------------------

#7 10 Aug 2007 20:04
avery_larry


Very nice (now that I finally looked!).
Post Reply