Wednesday, October 24, 2007

Don't use bat files anymore: Automate your MS Windows tasks using JScript

Being a Unix geek I am quite used to automating my routine system administration tasks using cronjobs. When it comes to Microsoft Windows there is of course the equivalent tool called Scheduled Tasks. Sure enough we can create a bat file to put our little scripts together, call them from our Scheduled Task and we have a similar automation to cronjobs. However there is one annoying side effect: In the middle of your work an ugly cmd-terminal-window-thing pops up, spits some text and disappears before you can read even a word. It is simply your bat file run by the scheduled tasks tool and its output.

I wanted to find a better way of doing this and, I have spent a bit of time googling about Windows Scripting and JScript. I wanted to use JScript because (putting it quite crudely) it is Microsoft version of Javascript, which I know much better than VB. I used to write VB (Basic more like) in the past, but thats another story.

Turns out it is quite easy. I used a Microsoft specific object WScript to run my tasks and the rest was basically Javascript.

Running A Command:

First you need to instantiate an ActiveXObject of WScript.Shell:
var shell = new ActiveXObject("WScript.Shell");
Then you can run commands like this:
shell.Run("yourcmd", 0);
The second argument to Run method makes sure to not display the 'ugly' command window while running our little shell command.

Print Debugging:

It is inevitable that you will need to check your scripts problems unless it is a very simple short one. I am sure there are quite elegant ways of debugging your script (you might need something like Visual Studio for this, I am not sure) nevertheless a few 'print' statements here and there can be very effective as well. Unfortunately there is no straight print command in JScript but this does the job as good as print:
WScript.Echo("Hello!");
Just save your script with a .js extension and you are in business.

Tuesday, October 23, 2007

Javascript Service: Simple way of embedded scripting

It has been quite a while since I last wrote something (Don't be fooled by the post date). This one has been waiting in my drafts and some how could not find the time to publish it. Anyway, here it is in Google Code (in my special incubation repo):

http://code.google.com/p/zeealpha/downloads/list

Maybe I post another log on how to use it later.

Friday, October 05, 2007

One Way to Debug Perl CGIs

They are old fashion but you might be stuck with them or prefer them for one reason or another. Especially if you have a few legacy ones in your hand you probably had problems debugging them now and again. Well yes. I am talking about CGIs.

When I have an issue with a (Perl) CGI first I'd do one of two things: if I can throw it away (or better put; get rid off the CGI dependency in my code) then I start my new code immediately. But if I can't (because of the amount of code or the complexity) then I start debugging. And when you debug a CGI there aren't much choice: Use print statements here and there! Yes, I know there are some IDEs offering debugging capabilities, but I am talking about a hard core vi and perl -d scenario.

So what to do if your print statements are getting too much? They can become very time consuming very quickly. Then what about good-old perl -d command line debugging? Well, it's simply not an option since the web server is executing the script and you have no control over it.

While I was struggling with one of my notorious CGI scripts I thought of a rather ingenious idea: What if I could capture the CGI inputs and then replay them while I am running the script from the command line.

First thing I needed was the environment variables. Web servers set quite a few environment variables before executing the CGIs. These are things like the clients IP address, query string and many more related to the current request, web server and the script itself. Saving them and loading them are quite easy; just use the %ENV hash:


Created with colorer-take5 library. Type 'perl'

# Capture
use Data::Dump;
open $fh, '>', 'dump_file';

print $fh Data::Dump::dump(\%ENV);
close $fh;

# Replay
%ENV = %{ do 'dump_file' };



This would be enough if you don't have any POST requests. When it comes to POSTs you need STDIN as well. This is a bit more trickery to load:


Created with colorer-take5 library. Type 'perl'

# Capture
read(STDIN, $buf, $ENV{CONTENT_LENGTH});

open $fh, '>', 'dump_stdin_file';
print $fh $buf;
close $fh


# Replay
open STDIN, '<', 'dump_stdin_file';


And there you go. You can now capture and replay your CGI requests adding these on top of your Perl CGIs and enjoy the power of command line debugging.