Tuesday, February 16, 2010

Mpath: command-line path manipulation for Windows

I'm a command line geek. Windows' style of installing everything in its own directory makes it easier to clean up after uninstallation, but it makes for very long PATH environment variables. If I put every directory containing command line tools in the system path, it gets too long for Windows to handle. So I usually end up doing "PATH=%PATH%;c:\somethingelse\bin" just before I use it. That also makes for long paths over long runtimes, especially when you use it in batch files (since you end up with PATH=c:\somethingelse\bin;c:\somethingelse\bin;c:\somethingelse\bin;[rest of path] after multiple invocations).

So I wrote mpath. Mpath is a combination batch file and Python script that takes advantage of some quirks of the Windows command shell, to let a child process alter the environment of a parent command shell process (something that you typically can't do in win32, but mpath gets around it by creating a temporary batch file that gets executed in the parent process).

Syntax:

  • mpath pathname : prepends pathname to the current command shell's PATH, if it doesn't already exist.
  • mpath + pathname : appends pathname to the current command shell's PATH, if it doesn't already exist.
  • mpath - pathname : removes pathname from the current command shell's PATH, if it exists.

A quick demo:

C:\> PATH=C:

C:\> PATH
PATH=C:

C:\> mpath c:\foo (prepend c:\foo to the path)

C:\> PATH
PATH=c:\foo;C:

C:\> mpath - C:\FOO (take it off the path--note case insensitivity)

C:\> PATH
PATH=C:

C:\> mpath + c:\foo (append c:\foo to the path)

C:\> PATH
PATH=C:\;c:\foo

C:\> mpath c:\foo (try to prepend it again--mpath knows it's already there)
c:\foo already in path.

C:\> PATH=%PATH%;c:\foo (silly user should have used mpath...)

C:\> PATH
PATH=C:\;c:\foo;c:\foo (now there are two copies!)

C:\> mpath - C:\FOO (but mpath takes care of that.)

C:\> PATH
PATH=C:


I've tested Mpath with Windows XP running Python 2.5 and 2.6. I know it doesn't work on 3.x; I plan on fixing that at some point when I need it.



Update: mpath is now tested on 2.5, 2.6, 2.7, and 3.1.