GNU Screen is a remote terminal multiplexer, described welll elsewhere.
I use it to eliminate the too-many-Terminal-windows problem on my laptop. I also use it to help me achieve some level of continuity on remote hosts, by leaving half-completed sysadmin tasks as-is until hours or days later even if I get interrupted or if the task is really long-running and I need to roam around with my laptop.
Today I decided to invest some time in making my command-line development environment launch with a single script. Here are the details.
Since Screen can preserve context and state only until the host it’s running on is rebooted, I use a text todo list to make sure the big tasks don’t get forgotten or done out of order. On remote hosts I keep this todo list open in a screen by itself, and make other screens for individual steps like “apt-get update” etc. Usually I can go away and come back a couple of days later and pick up where I left off, but if there’s a reboot (which happens occasionally with a VPS I don’t control fully) the todo list is still there as a backup means of remembering where I was.
Locally, though, my todo list is a text file managed in a GUI editor, which lately is TextMate. So all that has to happen throug Screen is the command-line stuff itself.
I used to set things up manually when starting a development session (which could last hours or days, depending on Software Update, travel, etc.). That took a couple of minutes because I had to launch Locomotive, use it to open a Terminal window with the right shell environment, then run screen -e^oo and manually open a bunch of screens, then manually change their titles, then manually run a few tools and stuff.
Now I have all that automated. There’s a shell script that sets the environment up (it’s just the same script that Locomotive makes, but copied out of /tmp into a stable place, since the contents are stable and don’t need to change for each new session). That calls screen -c jamie_screenrc whose contents are below (sanitized a bit):
screen -t 'Rails project root' 0
# I like to have SVN running at the root of the whole project
# (including specs, notes, etc. with source code changesets)
screen -t svn 1
# screen/stuff are separated so that when you exit the stuff-ed program,
# you drop back to the bash shell for that screen instead of immediately
# exiting that screen. This is useful for "^c, up-arrow, enter" restarting of commands
screen -t psql 2
stuff "/opt/local/lib/postgresql82/bin/psql -U myprojectdev\\012"
screen -t autotest 3
screen -t mongrel 4
screen -t script/console 5
It’s “jamie_screenrc” and not ~/.screenrc so I can develop with the same setup on another host just by checking out the code (including this screenrc file) and running screen there. I don’t want this to be my default screen setup every time I run it anyway.
This is “mildly convenient” to quote Professor Frink. But it’s a big deal to me because now the barrier to starting and stopping work is very, very low; if I have a spare couple of minutes and I’m not set up to develop, I can get going in seconds. Likewise I don’t have to put off other things since I know I can stop and do anything else and get right back into flow very quickly.
The next step will probably be to create a RubyOSA script (or maybe just a shell script, if it’s sufficient) to get Firefox and TextMate and OmniGraffle up and running too with the right documents open just where and how I want them. Then I’d be able to run a single script (or click a single icon, in the Dock perhaps) and wait a minute or less and be completely ready to start coding.