Taming the Schedule, Part 1
June 5th, 2008

by Michael Swanberg

Ever wished you could turn your computer into a machine that does all of your mind-numbingly boring tasks for you? Here are some tips on doing that.

This will be a multi-part article on some things I have done to tame my Windows scheduler. I am not addressing Mac or *nix scheduling here, because those are much more robust systems for such things. The Windows Task Scheduler is pretty robust itself, but it can use some help.

First of all, I wanted to get into an idea that’s common on *nix platforms, as well as on Macs. They seem to obscure their schedulers a bit, but set up basic needs and make it very easy to do most of what you need to without much muss nor fuss. As such, Macs have cron, which is, for the most part, deprecated in favor of launchd.

Launchd often uses a built-in script called periodic to accomplish its tasks, which are to run everything in a specified folder at certain times. As such, automating regular jobs (such as backups or the like) is as easy as dropping a script into a specified folder. Periodic takes a single parameter, which is either one of “daily,” “weekly,” or “monthly,” or else the path to a folder. The daily, weekly, monthly parameters aren’t magical, they’re just pre-defined folders. Once periodic is invoked with the parameter, it goes about executing every script in the indicated folder.

Wouldn’t it be great if Windows had such a thing? Well, sadly, it doesn’t. But that doesn’t mean we can’t write our own, right? Open notepad and copy the following code into it and save the result as Periodic.bat. Make sure to allow Notepad to save with an extension other than .txt.

@echo off
pushd %1
for %%f in (*.bat *.pl *.vbs *.jcl *.ftp *.lnk *.exe *.com) do (
echo %%~ff
start /MIN cmd /c %%f
)
popd

Alright, for any of you who aren’t familiar with Windows batch language (far less-powerful than BASH shell scripting, but still somewhat useful), let’s go through the code, line by line.

The first line, “@echo off” basically says, “don’t show the commands as they’re being executed.” Any command can be proceeded with an “@” symbol to suppress the command itself being shown as it’s executed, but “echo off” extends this over the entire script. And giving it the “@” suppresses itself as well. Basically, it’s just cleaner. This line can be commented out to show what’s executing for debugging purposes.

The “pushd” line and the “popd” line (at the end of the script) are just housekeeping niceties. We need to get to the folder where the drove of scripts are, waiting to be run, but if we simply “cd” to that folder, then we can’t get back to where we came from. Periodic is likely to be run by other scripts, so we want this script to have a very low impact, meaning that it will return us to where we were when we started. Pushd does the same thing as the cd command, in that it changes the current working directory to that specified, but it takes the current directory and pushes it onto a stack (last-in-first-out). Then later, when we use the popd command, it brings us back to the directory where we were when we did the pushd. The “%1″ means the first parameter passed to the Periodic.bat script.

I could have just executed each script in the folder by specifying its location explicitly, but I wanted each script to run in the context of its own location. I like to use relative locations in my scripts where possible to increase script portability, and starting a script with the current working directory where the script itself lives is good practice.

Obviously, a good programmer would make sure that %1 is indeed a folder and indeed exists. We’re just going over the basics, here, so there won’t be a lot of checking. Just be careful… if you pass in a bad location for %1, then the Periodic script won’t move anywhere and consequently you will be executing every script in God-knows-where. If anyone wishes to add in the valid-directory-check code and post it in the comments, please feel free. Collaborative coding efforts are always far better than lone-wolf programming.

The next line is the “for” line. The for command in Windows batch language is a very misunderstood, but also very powerful, command. This is the simplest form of the for command in that it is gathering up all of the files in the current folder that match the listed formats and returns them, one by one, to the variable specified, in this case %%f. Note that I specified only the types of files that I wished to be executed. You may wish to change this to suit yourself. These extensions are, respectively, batch programs, Perl scripts, VisualBasic Scripts, MVS JCL scripts (more on this later), ftp scripts (again, more later), Windows shortcut links, executable programs, and small (smaller than 64k footprint) programs. I don’t create many exes or coms, so I could have probably left those out, but c’est la vie.

Then, for each of these files, I process them one by one through the lines contained in the parentheses. The echo command simply displays on the console whatever’s passed to it (with the exceptions of “off” and “on”, which we talked about earlier). The “~f” in the middle of the “%%f” causes only the filename to be displayed. So, if the program that’s being executed is, say, c:\Jobs\Daily\Backup.pl, then this line will display just Backup.pl. Essentially, this is just a courtesy line to say, “hey, I’m running this file now.”

Finally, the “start…” line is what’s really in-depth about this script. It can also be highly customized to suit your own needs. Start will open a new window to execute what’s passed to it. I did this for a multitude of reasons. First of all, if some error in a script ends the execution of the Periodic.bat script, well then the scripts farther down the line won’t get executed. I didn’t want the execution of any of my timed jobs to be affected by the misbehavior of any of the others scripts. So I run each in its own window. I also used start so that I could use the /MIN parameter, which starts the new window minimized, which will keep it from jumping in front of anything I am working on at the moment. This also allows all of the jobs to run simultaneously, instead of one after another. You may wish to have jobs run in serial fashion, so you can change this line accordingly, but you could also always have a script in the %1 folder that calls other scripts one at a time.

The “cmd /c” part of this line bears notice. Part of what start does is open a new window for execution. Trouble is, it won’t close that window when it’s finished. The /c parameter of the Windows command shell (cmd) closes the window once it’s finished with its task.

Finally, the “%%f” command is passed, which is the script that’s been gathered as part of the list. Essentially, the whole start line is saying, “start %%f in a new minimized window and close it when it’s finished.”

Next time, I’ll talk about how I set all this up to be scheduled and some of the (somewhat) clever things I did in that arena.

Oh, the .jcl and .ftp files. Well, where I work is an IBM MVS mainframe shop. I have to run jobs on the mainframe from time to time, but I am more of a PC jockey than a mainframer. So I discovered that JCL jobs can be ftp’ed straight into the mainframe’s execution spool. I have a small batch program that I set up and associated with the .jcl extension that ftp’s the job to the mainframe and executes it there. Since it’s associated with the .jcl extension, I can consider these files as scripts themselves.

I also wrote a small batch script for .ftp files and associated it with the .ftp extension. Windows has an ftp program, called ftp (duh), which can take in a list of commands to run in a batch mode (as opposed to interactively). Executing “ftp -s:” will run that ftp. So if there’s a file that you need to periodically ftp to or from a server, this is a great way to do it. Now I can double-click on the .ftp file or even schedule it to run automatically, which is far better than doing it manually through some GUI program, don’t you think? Unfortunately, however, the .ftp file must have my username and password in it, in clear text, so it’s not the most secure of methods. I need to write a full program that checks the server and uses the proper username and password which are stored in a secure, encrypted location. But that’s a project for another time. As such, I try to keep my use of .ftp files to a minumum.

So there it is, the guts of my scheduling system. Using this Periodic script, it is easy to set up drop folders for jobs to run at certain times. Then all that’s left is scheduling an execution of Periodic.bat passing it the location of the drop folder and voila, you have just set up the execution of all of the scripts therein. It can also be run manually. Just go to start/run and type in “Periodic ” and it runs.

Oh, I guess I should mention, it helps immensely to have Periodic.bat somewhere on your “path.” I created a folder, c:\Path, that I placed on my execution path (where Windows goes to look for programs when the program’s location isn’t explicitly specified). I keep all sorts of little goodies in there (like sed, awk, grep, lame, faad, cygwin.dll, md5, etc.).

Good luck. Let me know your feedback. I’m sure there will be plenty.

Share This Article:
  • Digg
  • del.icio.us
  • IndianPad
  • StumbleUpon
  • Technorati



Related Posts on This Topic:
Taming the Schedule, Part 2
What I Would Like To See…
The Google Grace Period for New Websites
Intel Inside… Your TV???
What is Podcasting? (part 1)


Leave a Comment


« Summer Movies Continue: Indiana Jones and the Last Crusade of the Raiders of the Kingdom of the Temple of the Doomed Crystal Skull Ark Taming the Schedule, Part 2 »
Copyright © 2004-2008 DailyIndia.com  Subscribe in a reader