{"id":27,"date":"2007-06-12T22:20:05","date_gmt":"2007-06-13T04:20:05","guid":{"rendered":"http:\/\/www.pervasivecode.com\/blog\/2007\/06\/12\/gnu-screen-and-my-screenrc\/"},"modified":"2007-06-12T22:20:05","modified_gmt":"2007-06-13T04:20:05","slug":"gnu-screen-and-my-screenrc","status":"publish","type":"post","link":"http:\/\/www.pervasivecode.com\/blog\/2007\/06\/12\/gnu-screen-and-my-screenrc\/","title":{"rendered":"GNU Screen and my screenrc"},"content":{"rendered":"<p>GNU Screen is a remote terminal multiplexer, described welll <a href=\"http:\/\/en.wikipedia.org\/wiki\/GNU_Screen\">elsewhere<\/a>. <\/p>\n<p>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.<\/p>\n<p>Today I decided to invest some time in making my command-line development environment launch with a single script. Here are the details.<br \/>\n<!--more--><\/p>\n<p>Since Screen can preserve context and state only until the host it&#8217;s running on is rebooted, I use a text todo list to make sure the big tasks don&#8217;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 &#8220;apt-get update&#8221; etc. Usually I can go away and come back a couple of days later and pick up where I left off, but if there&#8217;s a reboot (which happens occasionally with a VPS I don&#8217;t control fully) the todo list is still there as a backup means of remembering where I was.<\/p>\n<p>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.<\/p>\n<p>I used to set things up manually when starting a development session (which could last hours or days, depending on <a href=\"http:\/\/www.apple.com\/macosx\/upgrade\/softwareupdates.html\">Software Update<\/a>, travel, etc.). That took a couple of minutes because I had to launch <a href=\"http:\/\/locomotive.raaum.org\/\">Locomotive<\/a>, use it to open a Terminal window with the right shell environment,  then run <code>screen -e^oo<\/code> and manually open a bunch of screens, then manually change their titles, then manually run a few tools and stuff.<\/p>\n<p>Now I have all that automated. There&#8217;s a shell script that sets the environment up (it&#8217;s just the same script that Locomotive makes, but copied out of \/tmp into a stable place, since the contents are stable and don&#8217;t need to change for each new session). That calls <code>screen -c jamie_screenrc<\/code> whose contents are below (sanitized a bit):<\/p>\n<pre>\r\nescape ^oo\r\n\r\nscreen -t 'Rails project root' 0\r\n\r\n# I like to have SVN running at the root of the whole project\r\n# (including specs, notes, etc. with source code changesets)\r\nchdir \"..\/..\/..\"\r\nscreen -t svn 1\r\nchdir \"Site\/trunk\/myproject\"\r\n\r\n# screen\/stuff are separated so that when you exit the stuff-ed program,\r\n#  you drop back to the bash shell for that screen instead of immediately\r\n# exiting that screen. This is useful for \"^c, up-arrow, enter\" restarting of commands\r\n\r\nscreen -t psql 2\r\nstuff \"\/opt\/local\/lib\/postgresql82\/bin\/psql -U myprojectdev\\\\012\"\r\n\r\nscreen -t autotest 3\r\nstuff \"autotest\\\\012\"\r\n\r\nscreen -t mongrel 4\r\nstuff \".\/script\/server\\\\012\"\r\n\r\nscreen -t script\/console 5\r\nstuff \".\/script\/console\\\\012\"\r\n\r\nselect 0\r\n<\/pre>\n<p>It&#8217;s &#8220;jamie_screenrc&#8221; 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&#8217;t want this to be my default screen setup every time I run it anyway.<\/p>\n<p>This is &#8220;mildly convenient&#8221; to quote <a href=\"http:\/\/en.wikipedia.org\/wiki\/Professor_Frink\">Professor Frink<\/a>. But it&#8217;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&#8217;m not set up to develop, I can get going in seconds. Likewise I don&#8217;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.<\/p>\n<p>The next step will probably be to create a <a href=\"http:\/\/rubyosa.rubyforge.org\/\">RubyOSA<\/a> script (or maybe just a shell script, if it&#8217;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&#8217;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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <a href=\"http:\/\/www.pervasivecode.com\/blog\/2007\/06\/12\/gnu-screen-and-my-screenrc\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;GNU Screen and my screenrc&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,9],"tags":[],"class_list":["post-27","post","type-post","status-publish","format-standard","hentry","category-linux","category-mac","category-tools"],"_links":{"self":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/posts\/27"}],"collection":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/comments?post=27"}],"version-history":[{"count":0,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/posts\/27\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/media?parent=27"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/categories?post=27"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/tags?post=27"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}