Since MongoDB was first created, the Mongo shell prompt has just been:
>
A couple of months ago, my prompt suddenly changed to:
myReplSetName:SECONDARY>
It’s nice to have more information the prompt, but 1) I don’t care about the replica set name and 2) a programmer’s prompt is very personal. Having it change out from under you is like coming home and finding that someone replaced all of your underwear. It’s just disconcerting.
Anyway, I recently got an intern (well, I’m mentoring him, it’s not like I bought him), Matt Dannenberg, who’s interested in working on shell stuff. He committed some code last week that lets you customize the shell’s prompt (it will be in 1.9.1+).
Basically, you define a prompt() function, and then it’ll be executed every time the shell is displayed. Immediately, I did:
myReplSetName:SECONDARY> prompt = "> " > > // ah, bliss > > // some sysadmins think > is a weird prompt, as it's also > // used for redirections, so they might prefer $ > prompt = "$ " $ $ // there we go
Okay, that’s much better. But there is some information I’d like to add to my prompt.
I often forget which database db is referring to, and then I have to type db to check (which is especially annoying when I’m in the middle of a multi-line script). So, let’s just add the current database name to the prompt.
> prompt = function() { return db+"> "; }
test> use foo
foo> use bar
bar>
The prompt no longer shows whether I’m connected to a PRIMARY or a SECONDARY (or something else), which is useful information to have. I hate that long string, though, so let’s neaten it up. I want it to be:
foo>- I’m connected to the primary
(foo)>- I’m connected to a secondary
STATE:foo>- I’m connected to a server with state STATE.
This might look something like:
> states = ["STARTUP", "PRIMARY", "SECONDARY", "RECOVERING", "FATAL",
... "STARTUP2", "UNKNOWN", "ARBITER", "DOWN", "ROLLBACK"]
>
> prompt = function() {
... result = db.isMaster();
... if (result.ismaster) {
... return db+"> ";
... }
... else if (result.secondary) {
... return "("+db+")> ";
... }
... result = db.adminCommand({replSetGetStatus : 1})
... return states[result.myState]+":"+db+"> ";
... }
(test)>
Also, the default prompt displays if you’re connected to a mongos (with mongos>), which is good for keeping track when you’re running a cluster:
> prompt = function() {
... result = db.adminCommand({isdbgrid : 1});
... if (result.ok == 1) {
... return "mongos> ";
... }
... return "> ";
... }
Another nice thing would be to have the time each time it displays the prompt: then you can kick off a long-running job, go to lunch, and know what time it finished when you get back.
> prompt = function() {
... var now = new Date();
... return now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+"> ";
... }
10:30:45> db.foo.count()
60000
10:30:46>
Defining prompt() as shown above is nice for playing around, but it’s a pain to define your prompt every time you start up the shell. So, you can add it to a function and then either load it on startup (a command line argument) or from the shell itself:
$ # load from command line arg:
$ mongo shellConfig.js
MongoDB shell version 1.9.1-
connecting to: test
>
> // load from the shell itself
> load("/path/to/my/shellConfig.js")
Or, you can use another feature my intern has implemented: mongo will automatically look for (and, if it finds, load) a .mongorc.js file from your home directory on startup.
// my startup file
prompt = /* ... */
// getting "not master and slaveok=false" errors drives me nuts,
// so I'm overriding the getDB() code to ALWAYS set slaveok=true
Mongo.prototype.getDB = function(name) {
this.setSlaveOk();
return new DB(this, name);
}
/* and so on... */

Keep in mind that the is a “proper” JS file, you can’t use magic Mongo shell helpers, like use <dbname> (instead, use db.getSisterDB("<dbname>")). If you don’t want .mongorc.js loaded on startup, start the shell with –norc.
Hopefully these things will make life a little easier for people.
Both of these changes are in master and will be in 1.9.1+. They will not be backported to the 1.8 branch. You can use the 1.9 shell with the 1.8 database server, though, if you want to use these features with a production database.
