Monday 28 September 2009

A combined shell and terminal

Last year I wrote about a couple of features that I'd like to see in a hypothetical integrated shell and terminal.

Since then I have implemented my idea! The result is Coconut Shell. It is a combined shell and terminal. It is intended to look and behave much the same as Bash + GNOME Terminal. I am now using it as my main shell/terminal.

I find the most useful feature is finish notifications: When a long-running command finishes, it flashes the window's task bar icon. A trivial example:

Now I no longer have to keep checking minimised windows to see whether a build has finished or whether packages have finished downloading and installing.

It works with tabs too:

This had an unforeseen benefit. It helps when I'm testing GUI applications. When I close down the GUI application, the tab that I ran the application from gets highlighted, which makes it easier to find the tab to re-run the app from. I don't search through windows as much as I used to. (I tend to have a lot of terminal windows and tabs open at a time!)

How it works:

Coconut Shell is implemented in Python. The terminal and shell run in the same process. It uses libvte to provide the terminal emulator widget -- the same as GNOME Terminal. It uses Pyrepl as a readline-alike to read commands from the terminal.

Normal shells rely on Unix process groups to stop backgrounded jobs from reading from the terminal. Coconut Shell doesn't rely on process groups in the same way. Instead, it creates a new TTY FD pair for every command it launches, and it forwards input and output to and from the terminal. This is partly out of necessity (process groups get in the way of reading from multiple TTY FDs at the same time), and partly because it is more robust. It stops jobs from interfering with each other and making themselves unbackgroundable. It also demonstrates that Unix never needed the whole sorry mess of process groups and session IDs and the weirdness they inflict on TTY file descriptors, because job control can be done by forwarding IO instead.

There's more information on the home page.

4 comments:

Toby said...

Nice, but does it do POLA? ;)

More seriously, I'm guessing the idea of proxying file-descriptors came from Plash. I wonder if there are any other good features that a shell could implement using this technique.

Meanwhile, could I ask about the current status of Plash?

Cool post. Thanks.

Mark Seaborn said...

It does a little bit of POLA. :-) See the "fake sudo" feature in the README file. When you run the shell as root, commands prefixed with "sudo" are run as root (passwordless), but other commands are run as a normal user.

I'd like to rewrite Plash's pola-shell in Python as part of Coconut Shell.

Recently I have been fixing Plash to build on the latest releases of Ubuntu and updating it to use glibc 2.10. I need to get the autobuilder running again and do a release.

Toby said...

Great. Looking forward to a new Plash release.

John Lee said...

Go, plash! Plash, go!

Just a bit of cheer-leading.