Old Content
This content is old! It’s still useful, but it’s old, and there may be bit rot, newer/better tools or ways to do things. Sanity check and do your research.
This article is translated to Serbo-Croatian by WHGeeks. Thanks!
I plan to move much of this to https://github.com/vossenjp/ at some point…
Introduction
The term “shell script” comes from UNIX, the DOS term is “batch files.” UNIX shell scripts are very powerful and flexible, they are essentially programming languages unto themselves. Windows or more rightfully DOS batch files are a pale imitation. However, sometimes you need to write something that will just work on any plain old out-of-the-box Windows install someone has–without adding all kinds of other tools.
Before getting too deep into this topic, consider if there is another tool you might use. Here is a list of tools, all of which are far more powerful, flexible and are probably easier to use than batch files:
- Perl ( Perl for Windows)
- JP Software’s 4Dos (now free) & TCC/LE (was 4NT, now free) (almost as powerful as UNIX shell scripts, but with a DOS/Windows “flavor”)
- NirCmd Freeware command-line tool
- UNIX tools ported to DOS/Windows, e.g. the UnxUtils and GNU Win32 ports.
- Bash or other UNIX shells ported to DOS/Windows, e.g. the CygWin project. It may not be totally obvious how to get things at the Cygwin site. Either download the “ setup.exe” program, which will guide you through everything, or use the mirrors page to find a mirror site and get everything yourself.
- AutoIt Free scripting and installation language for 95, 98, ME, NT4, 2000, XP, 2003. No run-times and may be compiled into an EXE.
- KixTart (and a KixTart script library)
- REXX
- And there are tons of other free scripting tools for Windows out on the ‘Net.
Powershell
If you follow Windows at all you will be aware that Powershell is Microsoft’s new command line tool, and that you will be required to use it more and more with newer Windows versions. That is a Good Thing, in my opinion, and it only took them about 20 years to realize, but that is not covered here! I don’t really do Windows anymore and I have not bothered to learn Powershell, which reminds me unpleasantly of Java’s verbose ugliness. So this page is somewhat historical, though most everything should work to at least Win7.
If you are interested in current Windows command line scripting and Powershell (and if you like Windows you should be), there are any number of other resources and books that will help. These are probably good but I haven’t read them:
- Windows PowerShell for Developers
- Windows PowerShell Cookbook: The Complete Guide to Scripting Microsoft’s New Command Shell
A Tweak
Did you know that Window’s cmd.exe has file and directory name
completion, like UNIX shells? It does, and that can be amazingly useful.
But in most versions of Windows it’s not turned on by default. (I
believe it may be on in Windows 2003, but can’t swear to it.)
To enable file and directory name completion under Windows, download
this registry file and remove the
.txt, then double-click on it and answer yes to the question about
importing into the Registry. If you can’t download for some reason you
can copy the text below into a new file and import it, or just open
regedit, navigate to the key, and change the values for CompletionChar
and PathCompletionChar to 9. One you’ve done that, open a new command
prompt and type dir c:\win then hit the TAB key and watch what
happens. Of course the up arrow and other command line editing functions
will still work as always.
The Dirt
OK, if you are still going to go through with this, the first thing you need is Tim Hill’s Windows NT Shell Scripting, otherwise you don’t have a chance. For Windows 9x/ME, you are still toast, but for NT/2000 this book is really great. It’s the only way you can navigate the bazaar, inconsistent, contradictory and often asinine “scripting” language built into cmd.exe.
Using material from that book, plus my own almost 20 years experience with DOS batch files, I still had a hell of a time writing the following script. All it does is give you some basic file information (similar to UNIX stat) and tell you if a file will fit on a floppy disk.
The Scripts
Clicking on the name of a script will open that script in a new window.
- Stat v1.0 2000-12-03
- NT Batch file to provide similar info to the UNIX (file) stat command.
- nt-cmd.cmd v1.2 2001-08-29
- Sample/demo code I wrote after reading Windows NT Shell Scripting.
- drives v1.1 2000-01-11
- A tiny script to display active drives.
Simple Sleep
Another of the many lacking tools is a simple “sleep” command, but you can easily fake that using the “ping” command of all things. The following will “sleep” for about 5 seconds, give or take:
Obviously you adjust the 5 as needed for the number of seconds. You can even write a trivial “sleep” function in your scripts:
The Date
How to get and use dates and time in Windows scripts.
This is trivially easy in UNIX. You want to copy a log file to a dated name? “cp mylog `date ‘+%Y-%m-%d’`-mylog” will copy mylog to 2002-11-27 (as of this writing). What could be easier? But in Windows, it sucks.
There are two basic ways to approach this, both with advantages and disadvantages. The native way is the “for” and “date /t” commands under NT/2000/XP. These do NOT work under Windows 9x and they do not consistently use 2 digit time fields, which totally screws you up if you need the time. The second way is to use the UNIX date command, then do whatever you please. This is very flexible, but requires you to download and have the executable ( date) handy. You will also want to rename it (I use udate.exe) so you don’t conflict with the built-in date command.
UPDATE (2012-07-26): All versions of Unix “date” commands that I have tested under both WinXP and Win7 have a bug that causes them to skip skip Mar-11 and/or Apr-04! That’s pretty annoying but has never been fixed as far as I know. Since it affects both tools I’ve tested (UnxUtils and GNU Win32), I suspect the Windows strftime lib is the problem. But I can’t prove it. And someone else replied to the bug he could not reproduce the problem. So I’d say it’s something I’m doing, but I find it off that both the WinXP I’ve been using forever and a much newer Win7 do the same thing.
UPDATE (2003-06-07): Here is a third way that’s trivial! It seems there are built-in but undocumented environment variables %time% and %date% in Windows 2000. I have not tested other platforms (let me know if you do). Due to the format, you can’t easily use the date in file copy operations (for example), but the time should be OK. And it’s by far the easiest option if you are just going to display (writing to a log file or something).
Windows Trivial
UPDATE (2006-05-11): Here is a another trivial way! Thanks to Richard Blake (RBlake {at} nea {DOT} org) for this great hack. In addition to the above %time% and %date% variables, there is a %VAR:offset,len% construct documented for the SET command, which works elsewhere. As above, the use of a two digit time code can mess you up, but for just the date it will work very well. Code to deal with non zero padded hours is left as an exercise for the reader.
This RedmondMag.com Backup Basics in Windows Server 2008 R2 article expands on the same method, but they are not portable because they depend on how your system time is displayed, and that will vary from machine to machine based on locale and user preference. For example, I loath any date/time format except for ISO8601 so I have my Windows formats set as close to that as possible, which then breaks the assumptions in the first block:
Other Ways
- windate v1.0 sometime in 2001 or 2002 Native Windows Date commands
- unixdate v1.0 sometime in 2001 or 2002 Using a UNIX date command in Windows
Getting Input
There are various tools like ask.exe and choice.exe that allow you to get input. There there’s an even easier, although undocumented, way: set /P. As in:
That prompts the user with “Your Prompt Here!” and puts whatever they type into %MyAnswer%. Very cool.
Simple Utilities
Except for FindZero.bat, all of these batch files will work under DOS, or any Windows.
- DOS Commands are not case sensitive, unlike UNIX commands.
- An “@” as the first character of a line prevents the command from echoing whether echo is on or off.
- echo. will echo a blank line (CRLF).
- Command line parameters are specified with %1, %2, etc. not $1, $2 as in UNIX.
- %0 is the name of the program, as invoked. In other words, if you type “mybatch” %0 will be “mybatch”. If you type “c:\utils\mybatch.bat” %0 will be “c:\utils\mybatch.bat”.
- ^G is a ‘control G’ which makes the console beep. This tiny batch file has a ^G in in, which you can cut & paste into scripts. There are lots of other ways to get control characters into files, but they depend on your OS and text editor. In most DOS windows, holding down the <ALT> key while typing the ASCII code on the numeric keypad will produce that character. ^G is 007, you you hold down <ALT>, type 007 on the numeric keypad, then release <ALT> to get a beep.
- Tim Hill’s Windows NT Shell Scripting for much more information and detail. Much of the book applies to DOS and Windows (other than NT) as well.
AddPath.bat
MCD.bat
auto-ftp v1.2 1999-09-16
Automatically Download a file using FTP (not secure!).
CLR.bat
aformat v2.4 2002-11-09
Format Floppy with no user prompts.
SPrompt.bat
Requires ANSI.sys, included with DOS & Windows, or PC Magazine’s free AnsiCom.
WhoAmI.bat
Requires Microsoft Networking to be installed and active, and the DOS find command. If you have a UNIX find command in the path, you’ll probably get a “No such file or directory” error.
Sending e-mail
Something else that is taken for granted on UNIX is the ability to send e-mail from the command line or a script. As usual, windows makes this a challenge. There are a few free and commercial solutions for this, including but not limited to the following list (I’ve only ever used Blat):
- Blat “is a Win32 command line utility that sends eMail using the SMTP or NNTP protocols.”
- NTsendmail “is Highly Acclaimed UNIX Sendmail replacement for NT. NTsendmail is realeased under the GNU Public License. NTsendmail was designed to enable script writers to use their UNIX CGIs on Windows 95/98/NT/2000.”
- And I’m sure there’s at least one or two Perl modules that can do this.
Upload from Frontpage to your ISP
I used to use MS FrontPage to maintain this site (don’t ask me why). My old ISP did not support FrontPage or its extensions, for excellent security reasons. Using FrontPage to create pages, then uploading them to a hosted site is a gigantic pain in the ass because of the way FrontPage keeps all of its proprietary information in various “_VTI_CNF” and other subdirectories. So simply zipping up the directories and dumping them onto a host is not ideal. So I came up with the following solution.
The old code I posted to a Netaxs news group was WRONG in places! THIS stuff works.
I don’t use this any more, I use Hugo and Relearn.
Open issues are:
- If you do a ZIP, and upload it, but do not delete it from the PC, the next run will append, not overwrite. Your “diff” zip will just keep growing. You need to manually delete the zip file after each run is successful.
- Since find is working off of the modification time, if you move a file into the structure that has not been modified (i.e. a tool or utility program) it will not be picked up by a diff. You have to add that to the zip manually.
- upload.cmd v1.0 2000-12-14
- Upload.bat runs on my Windows workstation, and creates a ZIP file I can upload, but it does not grab the stupid “_VTI_CNF” directories!
- upload.sh v1.1 2001-01-24
- Unzip upload.zip and set permissions on www directory.
Windows Scripting Resources
- Master and Command Line: “Using the Windows GUI is fine–if you want to go slow. Learn to use the command line and move into the administration fast lane.”
- Scripting for MCSEs (details about the Scriptomatic)
- The TechNet Script Center
- MS Windows Scripting FAQ
This article is translated to Serbo-Croatian by WHGeeks. Thanks!
Old Content
This content is old! It’s still useful, but it’s old, and there may be bit rot, newer/better tools or ways to do things. Sanity check and do your research.