Monad : Microsoft’s .NET Answer To BASH and KSH?

One of the more interesting features coming with Microsoft 'Longhorn' is Microsoft Shell, a.k.a. 'MSH' or by its codename 'Monad'. Monad is a Unix-like command shell for Longhorn that aims to be as interactive as KSH or BASH, as programmable as Ruby or Perl, but with an object orientated base in Microsoft .NET. This blog posting by Wesner Moise sums it up well:

"Microsoft is introducing a new command-line shell, codenamed Monad, into Longhorn. If you have a Longhorn build, you can use the new shell by launching "msh.exe."

The Good

New-style commands (or commandlets, as they are called in Longhorn) are .NET libraries (plus associated .msh or .cmdlet file) that consist of classes driving from CmdLet. Through the magic of reflection, Monad performs all the parsing and validation of switches and maps them to properties of your new class. Attributes are used to indicate whether properties are mandatory, optional, or produce prompting if omitted. Monad also will eventually support Intellisense and help for cmdlets.

Commands can output .NET objects not just text. For example, you can enter

get/process | where "handlecount -gr 400" | sort handlecount | format/table processname,handlecount

You get:

ProcessName HandleCount
---------------- ---------------
processname handlecount
... ...

Get/Process returns a sequence of process objects, which is filtered to include only those processes with a HandleCount property exceeding 400, then sorted and formatted to show a table of two columns. These objects are treated like records, and can be output to various formats besides text, such as an Excel spreadsheet.

Other notables: In addition to the standard input, output, and error steams, there can be additional streams used by cmdlets such as for verbose mode, progress status, and debug mode. Drives can not just be mapped to the filesystem, but also to other heirarchies like the registry database. The scripting language is designed to be as powerful as Perl, as it includes typed variables, functions, property accessors and method calls, and associative arrays.

The Bad

The new shell, as it stands now, is not very usable as a routine interactive shell, so, at least in this build, you'll gravitate back to the familiarity and simplicity of cmd.exe.

Monad is not quite a superset of the XP cmd shell. You can execute traditional commands as before, but the built-in commands all behave different. For example, in the most basic of operations, listing the current directory (ie, typing "dir") produces the directory contents but in user-unfriendly manner. I sure hope that the new shell undergoes usability testing, since the new shell syntax is unfamiliar and does require learning."

I was reminded about Monad by a recent posting by Adam Barr (author of "Proudly Serving My Corporate Masters", one of the best books on the Microsoft developer culture) where Adam points out that a recent set of powerpoint slides on Monad got linked to on Slashdot.

What makes Monad particularly interesting (apart from the fact that it's finally a decent shell for Windows) is that each of the shell commands (known as "cmdlets" is in fact a .NET class - more analogous to a .DLL than an .EXE - and you can pipe data between objects using their published interfaces. This slashdot posting by Earlybird (56426) sums it up well:

"Microsoft is doing something interesting and innovating. The Unix world could use this.

Basically, Monad formalizes in .NET the pipe interface between shell programs. A pipe participant is just something that implements the appropriate "commandlet" interface: it receives some input, produces some output, maybe some errors.

However, in the case of Monad the input and output can be anything, not just text. So in the example:

get-process | where "handlecount gt 400" | sort handlecount | out-chart processname,handlecount

The get-process command produces a sequence of processes; where filters it based on an attribute; sort sorts on an attribute, and out-chart produces a textual table of the filtered output.

It's important that the input and output of these processes are structures (actually, objects, but I don't want to tickle anyone's prejudices about OOP). .NET knows at runtime about the attributes these structures can have, so you can write apps that manipulate a wide variety of object types: files, metadata-annotated documents, log entries, whatever.

Naturally input/output can be pure text, allowing all the traditional Unix commands such as grep.

Immediate benefit? If you have the right translator, there's no need to munge text output using awkward tools like tr, cut, awk and so on, just to get at the process ID column of ps or the URL column of the Apache log file.

This is better than Unix shells."

Interesting stuff. In terms of it's significance, another poster sums it up well with this the comment: "I actually feel its kinda complementary to the Unix shell environment. This looks more like VBA on steroids, the .NETized version probably. Passing around structures has been done in MS world for a long-time - excel sheet processing, macro viruses etc. I think similar results can be achieved using DCOP/KDE or the GNOME equivalent, probably KDE , GNOME hackers can comment on that." You can download the presentation here, read more here, and if you're interested in trying Monad out on XP or 2000 you can sign up for a beta (guest ID "'mshPDC") at http://betaplace.com.