Ok, so I've talked about how great the Monad language, and command-line interface
is. I've also said that it changes the way you think about the command line.
How so?
Well, let's play with the shell for a bit. If you haven't already downloaded it,
you can get it from BetaPlace:
1) Go to http://beta.microsoft.com
2) Log in using the guest ID, mshPDC
3) Follow the download directions
Launch the shell, and you're greeted with the friendly prompt:
MSH>
Friendly, but not as useful as it could be. Monad defines its prompt via the "prompt"
function. Let's create one. Oh, and let's make it have the current directory in
it. But how do we get that? One of the important commands to help you spelunk through
Monad is is called "get-command." Monad commands are always in the form of [verb]-[noun].
You always perform an action (verb) on something (noun.) Now, back to our goal:
MSH>get-command *directory*
Searching by the verb didn't help much, let's try a noun:
MSH> get-command get-*
Several items look promising. Specifically, get-location.
MSH>get-location
Drive Provider ProviderPath Path
----- -------- ------------ ----
C System.Managemen... C:\Documents and... C:\Documents and...
That looks like what we want. Remember when I mentioned that Monad was object-based?
Well here's an example of where we get to use that functionality. Here we go:
MSH>$location = get-location
MSH>$location.Path
C:\Documents and Settings\Lee
Ahh, that's exactly what we want. We've stored the results of get-location into
a variable, and then accessed its Path property. The two steps aren't actually required,
so we'll shorten them to:
MSH>(get-location).Path
C:\Documents and Settings\Lee
Here's another fun example -- find out how many 'get-*' commands Monad has. The
get-command call returns a list, so you can determine its size using the 'Count'
property:
MSH>(get-command get-*).Count
29
Perfect. Notice that we haven't ever had to do things like "echo", or use the command
"write-host." This is because the commands we call generate objects. When your command
generates an object, it flows to the next stage in your command. This sequence of
commands that you specify (separated by a | symbol,) is called a pipeline. The output
of one becomes the input of the next. Since we haven't specified any additional
stages, the Monad shell ultimately ouputs the final one to the default "sink" --
out-host. The out-host command tries its best to format its input suitable for display.
So, the implied command is:
MSH>(get-location).Path | out-host
C:\Documents and Settings\Lee
Now, back to our goal of customizing the prompt. As I mentioned earlier, you customize
your prompt by defining a function called "prompt." How do I know? Try "get-command
*prompt*"
MSH>function prompt { "New MSH Prompt>" }
New MSH Prompt>
Your prompt function simply emits a string, which the MSH host knows to output.
But, we don't want it to say "New MSH Prompt," we want it to output the current
directory (err, location):
New MSH Prompt>function prompt { "MSH " + (get-location).Path + ">" }
MSH C:\Documents and Settings\Lee>
Defining it this way will not persist between console sessions, though. To make
your changes permanent add the prompt function to your MSH profile, "profile.msh."
The default profile is actually nice enough the define a helpful variable called
"$profile":
MSH C:\Documents and Settings\Lee>notepad $profile
Notepad pops up with your current profile. Investigate it a bit, to see what it
does. You don't have to understand it all, but it does give you an idea of some
features that Monad supports. When you're done investigating, add your prompt function
to the file, then save it. I'll put mine as the first thing after the copyright
header:
...
# PARTICULAR PURPOSE
#
function prompt { "MSH " + (get-location).Path + ">" }
# If you set the environmental variable DebugMSH to 1, all script executions
...
Now, close your shell, reopen it, and enjoy your new prompt. However, we can make
it even better.
Command-line interfaces have long supported a facility to let you interact with
your console history. A lot of Unix geeks like to have their prompt display their
current history line number. That's for two reasons. First, it lets you invoke a
previous command by its history ID. Second, it somehow ties in with our freakish
obsession with uptime. It'll look like this:
MSH:1337 C:\Documents and Settings\Lee>
We'll cover it next time, but see if you can beat me to it.
[Edit: Updated .Length to .Count, as .Count is the standard!]
[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]