Saturday, November 15, 2003

Command Shell Liberation

I’ve been on a bit of a quest lately, looking for a better command line experience. I tried bash for a while (under Cygwin), and that was pretty cool. It took me back to my Unix days, and is clearly a first-rate product. But I kept running into differences between Windows idea of paths (e.g. C:\data\writing) and Cgywin’s idea of a path (e.g. /c/data/writing). Personally, I like forward slashes better, but since I’m stuck with Windows pathnames for a lot of applications, I was sort of screwed.

During the course of thinking about the problem, I actually realized that I really have two requirements that I had been confusing:

1) A nice interactive shell for doing things like executing programs and listing directories.
2) A scripting language for automating repetitive tasks.

Shells like bash and tcsh address both features, but really, they’re two separate things, and a large part of the value comes from all the other little command-line tools that are part of something like Cygwin, rather than from the shell itself. Those are available separately, so I figured if I could find two different products to satisfy both needs, then I’d be set. I’m playing with Python to see what I think of it for requirement #2. C# is an option there, too.

To figure out what to do about my first requirement, I asked around a bit, and some hard-core developers over on the Off-Topic Mailing List pointed me to 4NT as a good replacement for the Windows command shell. I downloaded the trial and had to agree that it is indeed pretty darn cool. But I think I’m going to stick with cmd.exe. The big reason I’m even contemplating this is this registry key:

HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun

According to the documentation, if you list a file under this key, it will be run at the start of every cmd.exe session. Well, this is awesome. It means that I can set it to something like C:\home\cmdrc.cmd and then populate the file with something like this:

@echo Running cmdrc.cmd
@SET PATH=c:\bin;%PATH%
@SET PATH=c:\bin ant-;%PATH%
@call vsvars32.bat

Now, whenever I fire up cmd.exe, it sets my path appropriately, and executes the vsvars32.bat file, which does all sorts of environmental goodness to enable programs like the C# compiler from the command line. Best of all, when I add a new program that I want to be able to run from the command line, I just have to throw a new line into my cmdrc.cmd file, and restart any command shells I have open. This is waaaay better than having to much around with the environment variables dialog box and having to kill explorer.exe. Plus, when I reinstall my system, it’s just a matter of copying this file over to preserve all my hard-fought configuration.



  1. Kill Explorer.exe? Why do you need to do that? I've never had to do that after editing environment variables.

  2. I was going to say the same thing as Kevin, but he beat me to it. :) When I set environment variables, I just have to close down any open command prompts. I've never had to kill explorer.exe.

  3. Interesting...I'm not sure where I got that notion, then. But regardless, I still hate navigating through to the stupid dialog that gives you a tiny little edit window where you can't even see the environment variables. Sure, I can copy and paste it out, but I think this is more convenient.

    On top of that, running an arbitrary command at cmd.exe startup still has a bunch of other useful benefits even aside from path manipulation. Running vsvars32.bat is just one example.

  4. Definitely a useful trick. I'm going to use it for the VCVARS32 trick.

    BTW, here's another option for setting env vars:

  5. Nice! That looks like a good tool to have in the ol' tool bag.

  6. TakeCommand/32 (which is the cross-OS version of 4NT, made by the same people) allows you to run commands pre-startup as well. It also lets you do some really incredibly handy stuff, like alias commands (including parameterized and recursive aliases, god forbid), delete to the recycle bin, colorize 'dir' output, run commands on lists of files either individually or as a group, along with about a bajillion other things (like sendmail, ftp, executing commands in every folder in a hierarchy, writing to the eventlog, creating shortcuts and hardlinks, etc. etc. ad infinitum). It's in my top-3 list of "most used tools."

  7. Aliasing is the one thing I really miss at the command prompt. However, a small batch file can often take care of this.

    But there are plenty of awesome features in 4NT/TakeCommand, no question about it. I'm just not sure how often I'd use them. On top of that, if I move around between computers (an important thing for a consultant like me), I can pretty much always count on being able to put free stuff on them.

  8. If you wanna stick to 4nt, there is also an 'autoexec'-like approach: create a file named 4start.btm on the installation directory of 4nt.

    It'll be executed for every new window of 4nt (much like the registry/cmd trick/hack).