Posterous theme by Cory Watilo

IPython as a replacement for bash (on a Mac)

Previously, I didn't imagine Python would be fast enough for shell usage. But I was wrong. I'd miscalculated that most of the slowness in a terminal is I/O bound (and then cached), and that main memory access, if within the 10,000 to 100,000 instruction range, is unnoticeable to a human on a fast enough box. I.e., the actual manipulation of text is not the bottleneck and is at most in the millisecond range for most commands. I believe in the 'psychology' of fast response times as much as the next person. But really IPython can be as fast as bash.

Here are some reasons you might want to use IPython for visualization and programming:

http://www.quora.com/What-is-IPython-and-why-would-I-want-to-use-it?q=ipython

Or a presentation by two of the authors (pdf):

http://fperez.org/talks/0702_pycon_ipython.pdf

But for a shell? Although it doesn't come installed to look like a shell out of the box, it's Python. You should be able to fix that. Not to mention, think about the rewards if you can push the Python boundary line upwards to include day-to-day administration. Think of how many more little elegant scripts you'd prototype from the command line and then would be almost half done with. Think about just the ability to import scripts from the command line.

Python and IPython Installation (on a Mac)

So you probably want to use the Macports (installs by default into /opt/local) version of Python 2.6. Simply to avoid the whole readline situation. If Python is installed with readline support and your .inputrc is setup correctly (e.g., with 'set editing-mode vi'), then you actually want to disable IPython's readline support later (see below). It's sort of weird but I think it's because readline is already baked inside Python. Plus it gets rid of the double forward slash in tab completion weirdness. And I'm pretty sure it's gotten rid of all the weird newline garbling (and if you like vi mode, you'll definitely appreciate that working; i.e., ESC, ^, etc..)

But at any rate, after installing Python from macports and updating your path to use /opt/local/bin first, you probably want to use the latest IPython from github:

http://mail.scipy.org/pipermail/ipython-user/2010-November/007247.html

Besides removing the seemingly accidental dependency on X11, this will allow you to customize it and then reinstall if need be. I wouldn't try to run IPython from your local build directory because it loads itself via the python modules path (remember you can always start Python and run 'import IPython; IPython' to determine which module has actually loaded).

Customizations

~/.ipython/ipy_user_conf.py mods:

import ipy_profile_sh #equivalent to ipython -p sh
o = ip.options
o.prompt_in1 = r'\C_Normal\u@\H:\Y5$ ' #basically via http://blog.afurlan.org/2009/10/29/using-ipython-your-default-shell/
o.prompt_in2 = r'\C_Normal... ' 
o.system_verbose = 0
o.confirm_exit = 0
o.banner = 0

~/.ipython/ipythonrc mods:

alias vi vim
alias ls ls -G
alias ll ls -altrh
alias dc cd
nosep 0
readline 0

This makes it look pretty much like bash. Again, I've installed IPython source from a local directory and then do python setup.py build / sudo python setup.py install to make changes. The only change I did so far was to comment out the uses_libedit section in rlineimpl.py. There's no 'Leopard libedit detected' in bash... :)

Caveats

'env' is persistent in a database. You don't need to set those in your ipy_user_conf.py or ipythonrc. Set it once and check env -p to be sure (http://ipython.scipy.org/doc/stable/html/interactive/shell.html ).

So there is this shell profile (set by 'import ipy_profile_sh' in ipy_user_conf.py or running ipython with '-p sh'), and that ensures that all commands which aren't found within IPython are sent externally. However, for overriding commands with the same name as predefined Python/IPython global values (like pwd), you may have to think a little more about what's going on under the hood.

E.g., piping stdin/stdout/stderr is a little different than you may be used to. I don't understand the exact details/internals/implementation of IPython yet; but I think whenever you start entering Python code, that stays within the Python process. E.g., suppose you have pbcopy. How could you pipe the current working directory into the clipboard? You have to force using the pwd from the shell (!pwd) and in fact stay within the shell:

!pwd | pbcopy

That is, pipelining can only occur within one ! ('!pwd | !pbcopy' is two different external system or popen3 commands, etc.). Takes a little getting used to -- probably worth looking at IPython/Shell.py.

More information

This has some pretty good links:

http://ipython.scipy.org/moin/Documentation

Including several screencasts (haven't had a chance to look at yet). Worth familiarizing over time. And of course browsing / acking / hacking on the IPython source....