views:

168

answers:

4

I inherited some large batch files, and I'd like to rewrite them to a more "developer friendly" language.

I'd like to find out the following things:

  • what other scripts it calls
  • what other processes it starts
  • what files does it write to
  • what environment variables it uses, which ones does it set

For the last point, I'm aware I can do this before I start:

set > original_environment.txt

And after I run it, I can do this:

set > new_environment.txt

and just do a diff between them ... but I'll probably miss some variables that may be unset when the script finishes ( or even all of them if the script's ran under setlocal ).

Is there any way of finding all those things without me adding tons of echo statements throughout the script code? Is there such a tool that can monitor the process started by the batch file and tell me everything it did?

+1  A: 

You can just look inside them and figure out what they do.

You can also remove any echo off statements and @ preceding commands; that way every command is output before it's run and you can redirect the output to a file to study it later.

There is no debugging tool for batch files that I am aware of—but I contemplated writing one once.

Joey
Yes, but I'd have to make sure all other scripts getting called also don't have the `echo off`. I'm thinking about the same thing about the tool :)
Geo
@Geo: The problem with such a tool would be that you have to accurately model cmd's behavior. And you can't just execute the lines one-by-one in cmd since that has often different results than when run from a batch file—a naïve approach would likely fail. Although I think I have an idea which *could* work—you simply write out another batch file, containing a `pause` statement after each line as well as writing the complete environment into a file for the debugger to grab. Might not be too pretty and keeping track of open files is another problem entirely. Process Monitor was a nice tip, though
Joey
+1  A: 

No, there is no way to debug old style batch files. You can, however, just get rid of all the ECHO OFF statements, and then all the commands and output will be echo'd to the console when you run them.

jeffamaphone
Any line starting with @ will also not be echoed
John Knoeller
+1  A: 

If you are willing to spend some money you should take a look at the Running Steps batch file IDE and its debugging capabilities.

I didn't test it, but it has some features that might help you in your task:

...

  • Visual Studio-like debugging environment.
  • Rich set of debugging commands (step into, step over, step out, and more)
  • Rich Project analyzer to find your errors and warnings in no time.
  • Integrated support for delayed-expanded environment variables.
  • Multi-type breakpoint definitions to fit your multiple debugging needs.
  • Complex pipeline and redirection support with multi-color highlighting.
  • Environment variable visualization and modification support.
  • Expanded information window for true variable definition visualization.
  • Impressive 'For command' unrolling feature.
  • Interactive callstack and Parameters window.

...

They also offer a trial version.

Frank Bollack
A: 

There is no direct way to do it. But it's not impossible to create one.

Since Windows XP/Vista/7 came out the good'ole set of DOS batch commands has been greatly upgraded, although not many uses them or even RTFM (FOR /??)

So here I give you, a simple pure-batch TRACER that utilizes the FOR /F line-parsing switch:

@ECHO OFF

FOR /F "delims=" %%L IN (%1) DO (

  CLS

  ECHO __________________________________________________
  ECHO                            ENV. VARIABLES *BEFORE*
  SET

  ECHO __________________________________________________
  ECHO                                               LINE
  ECHO %%L

  ECHO __________________________________________________
  ECHO Hit any key to execute the line ...
  PAUSE > NUL

  ECHO __________________________________________________
  ECHO                                            EXECUTE
  %%L

  ECHO __________________________________________________
  ECHO Hit any key to fetch the next line...
  PAUSE > NUL

)

ECHO END OF FILE

You can take it as a start and modify it as you go.

Here's how you'd use it:

DEBUG.BAT TEST.BAT

And I'll also give you a test file to try it out:

@ECHO OFF

ECHO Hello World! 
SET aaa=1
SET bbb=2

ECHO Doing step 2
SET aaa=
SET ccc=3

ECHO Doing step 3
SET bbb=
SET ccc=

ECHO Finished!

This DEBUG.BAT thing, however, due of its simplicity, has some limitations BUT which can be worked around if you slap enough BATCH-fu in there.

  • It cannot process multi-line blocks :: This can be worked around by having the FOR commands parse tokens and build the lines as they come in, and IF it encountered an open parenthesis, just dump the parenthesis block content to a temporary file and then call itself on the tempfile e.g. DEBUG tempfile.bat
  • It cannot process jumps :: You can of course, do an IF check for a GOTO label then do a FOR /F to parse out label itself, then maybe utilize the second argument %2of DEBUG.BAT to specify the label to jump to, in which case if this very argument is specified you'd just spin the FOR /F until the desired label came into view and then proceeds with normal debugging on the next line.
  • There is too much information from a single SET :: Just do what you did with the SET > before.txt and after thing but do it on each line and then run a cmd-line DIFF tools on the files (plenty are available on the net). Then you'll get a DIFF of each variable that has changed since last step. You might even be able to avoid the env. variables mess altogether by slapping in SETLOCAL and ENDLOCAL in there and then you'd get just the local SETs ... but YMMV.

Those are some. If you've found some show-stopping limitation or whatever enhancements would help you nail that last bug, feel free to just let me know (via the comments) and I'll try to help you if I can.

Hope this helps.

chakrit