blog

image of shell, photo by http://www.flickr.com/photos/fast-asleep/

Making the Windows Command Prompt Suck (slightly) Less

by

Making the Windows command line suck (slightly) less

If you’re a developer who’s ever worked on Windows, you’ve had to deal with the Windows Command Prompt, a.k.a. cmd.exe. So you know it’s terrible. It hasn’t changed appreciably in almost 20 years (since Windows 95), and even then it was pretty bad, especially if you had ever used a Unix shell (bash, zsh, even csh) or the Vax shell.

But if you still have to use it, there are ways to reduce the amount of pain you have to suffer. Read on…

Alternate terminals

Some people like to use what I’ll call "alternate terminal programs". These typically wrap cmd.exe (and other console/shell-like programs). I’m not going to say to much about these, other than that they exist. Here’s a couple:

Creating a cmd.exe “profile”

In the UNIX world, shells typically have a way for users to customize their environment when starting a terminal session.

Old-school DOS and Windows users will recall autoexec.bat, which performed much the same function, but this no longer exists in more recent versions of windows. It turns out, however, that you can still get the same basic functionality by setting a couple of (apparently not terribly well-known) registry keys.

HKEY_LOCAL_MACHINESoftwareMicrosoftCommand ProcessorAutoRun

and:

HKEY_CURRENT_USERSoftwareMicrosoftCommand ProcessorAutoRun

Obviously the HKEY_CURRENT_USER key applies just to the current user, while the HKEY_LOCAL_MACHINE key applies to all users on the local machine.

When these keys are set, the contents are run as though they were commands in a batch file whenever you open up a new instance of cmd.exe. If you set both keys, the HKLM key is run first, followed by the HKCU key.

What I like to do is create a file in my home directory called something like .cmdrc, and then set my HKCU key to something like:

call %USERPROFILE%/.cmdrc

This lets me set up the registry keys once, and then make modifications in a regular text file, which I find much more convenient.

Aliases in cmd.exe

Just about every UNIX user has a their own set of favorite command line customizations created with the alias built-in. While alias doesn’t exist in cmd.exe, you can get a similar effect using the venerable DOSKEY, which goes back to 1989. DOSKEY is still around in Windows today, and is actually more powerful than bash’s alias command.

DOSKEY has a macro facility which lets you set up simple aliases something like this:

doskey cd~=cd %USERPROFILE%

which is pretty nice, but doskey macros also allow you to use variables, like so:

  • $1 – $9: command line arguments
  • $*: everything on the command line after the macro name
  • $t: command separator

Note that the $t variable means your macro can actually include multiple commands. Doskey macros can also include anything else you could put use from the command prompt, so you can use IF/ELSE conditions, etc. So if you’re a batch language wizard, your macros can actually fulfill the function of bash functions in many cases.

I stick my macros in my .cmdrc file mentioned above, so they get loaded with every command prompt.

Command line utilities

A huge amount of the power of modern UNIX shells doesn’t come from the shell, itself, but rather from the plethora of command line tools available on UNIX systems.

Happily we can get pretty much all of these on Windows through the GnuWin project, which provides native Win32 ports of a huge variety of GNU utils.

Even better, you can install them all using this Chocolatey package: http://chocolatey.org/packages/GnuWin

You knew about Chocolatey, right?

Wget, make, grep, three flavors of Awk and so much more…

Here’s a list: http://gnuwin32.sourceforge.net/packages.html

AnsiCon

Ok, great, now we have tons of great GNU utilities, but they look so drab compared to how they look on a UNIX machine.

This is because a Windows console handles displaying color in a completely different way than a UNIX temrinal. UNIX terminals interpret inline ANSI escape codes, while Windows consoles rely on Win32 API calls to change the current color being displayed. Fortunately there’s a way to get the one translated into the other.

The Ansicon project provides a dll which translates ANSI escape codes into Win32 color API calls on the fly. So now you can get lovely color output from your GNU utilities, and neither the executable nor the console needs to know anything about it.

You can easily install Ansicon using either:

ansicon -i

which puts some setup code for Ansicon into the HKCU autorun registry key, or:

ansicon -I

which does the same thing, but in the HKLM key. I recommend using the latter.

The only problem with Ansicon is that it’s a bit tricky to set up. What I mean is that I’ve had to set it up in several different ways on different machines, for various different reasons. Usually the install commands above will just work, but sometimes it takes a bit of trial and error to get things working smoothly.

Clink

Using the tips above helps a lot to make the Command Prompt a nicer environment to work in, but the discriminating UNIX shell user will still be annoyed by the way file and directory completion works in cmd.exe, not to mention the complete lack of any kind of command completion.

But there’s a solution for this too. Enter CLINK, which is another DLL addon for cmd.exe, whith a host of improvements to cmd.exe. By injecting it into your console process you get:

  • command-line editing a la GNU readline
  • path completion which shows all the available options, rather than having to cycle through them all one at a time.
  • the ability to use Ctrl-V to paste into the console window
  • command and environment variable completion (which you can customize using Lua)
  • advanced history features like persistent history and history expansion
  • a dynamic prompt that can change each time it’s displayed (again customized using Lua)

Clink can be added to your autorun key using:

clink autorun

run:

clink autorun --help for more details

There’s not much in the way of online documentation for clink, but there’s relatively complete docs in the distribution itself.

No Silver Bullet

While the tricks above do help quite a lot with making the venerable Command Prompt easier to deal with, I’m afraid it’s still an ancient relic, and there’s just no (easy) way to fix that properly. It’s just never going to be that great. I hope this eases some of your pain, though (it certainly does mine).

If any of you out there have any more tricks I haven’t listed here, please post in the comments. I’m always interested in more ways to make dealing with cmd.exe a bit easier.

+ more

Accurate Timing

Accurate Timing

In many tasks we need to do something at given intervals of time. The most obvious ways may not give you the best results. Time? Meh. The most basic tasks that don't have what you might call CPU-scale time requirements can be handled with the usual language and...

read more