| Monday May 30th 2016

Stupid linux screen tricks

I use GNU Screen extensively to manage my work. Here are a few tips and shortcuts I’ve collected or developed…

1. Adding a status bar to screen. If you use screen inside screen, or screen on more than one machine, having a status bar is essential so you always know where you are. I have the following line in my .screenrc:
caption always "%{= kw}%-w%{= BW}%n %t%{-}%+w %-= @%H - %LD %d %LM - %c"
Now whenever I’m within screen, the bottom line looks like this, showing the names of all windows (and highlighting the active one), the hostname, and the date and time:

0 emacs 1 bash 2 farm5 @ulysses - Sunday 26 October - 16:06

2. Change the screen command key. For Emacs users, the default screen command key, C-a, is unacceptable. The following line in .screenrc changes it to C-o, which is still bound in Emacs, but less objectionable:
escape ^Oo

3. Shortcut resuming screen. Whenever I SSH to my desktop machine the first thing I do— always— is resume my previous screen session. The following command runs ssh and resumes screen in one fell swoop:
ssh -t ulysses "screen -d -r"

I stick that in a script called homebase and bind a hotkey, [Windows]-h, to

gnome-terminal -e ~/scripts/homebase

in Openbox so I’m only ever one key away.

4. Use nested screens. My desktop machine has good connectivity, so from my screen there, I connect to a bunch of remote machines which I use for my work, and of course, I use screen on those hosts too.

To send a C-o to a screen instance which is itself inside a screen window, you need to escape it and type C-o o. So, for example, if C-o n is usually used to go to the next window, you’ll need to use C-o o n to go to the next window in a nested instance. This setup is hard to beat for managing connections to multiple computers. It sounds complicated, but your muscle memory will take care of it soon.

5. Generate new windows automatically. Whenever I SSH into another host from inside screen, I usually want a dedicated window for that connection. The following snippet in my .bashrc makes it so that when I’m inside screen and type ssh SOME-HOST, it creates a new window and titles it SOME-HOST, then invokes ssh in the new window.

# Opens SSH on a new screen window with the appropriate name.
screen_ssh() {
screen -t ${!numargs} ssh $@
if [ $TERM == "screen" -o $TERM == "screen.linux" ]; then
alias ssh=screen_ssh

(Caveat: this doesn’t quite work when you specify a host and a command on the same line, e.g. ssh some-host "ls ~".)

6. Managing DISPLAYs. The disconnect-and-resume-anytime way of working can sometimes be a curse. Shells inside screen windows don’t get environment variables like $DISPLAY updated whenever you resume a session. So if you carelessly launch an X program from inside one, it may end up on a display which is either long gone or not the one you intended to use. The following simple trick automagically sets DISPLAY to the display at the last place you resumed a screen session (i.e. probably where you are sitting right now).

First, write the value of $DISPLAY to a file whenever you resume screen. One way to do this is by using a shell alias like the following whenever you resume, instead of using screen -d -r directly:

alias sc='echo $DISPLAY>~/.last-display; screen -d -r'
Alternatively, the invocation from #3, above, might now look like this:

ssh -X -t ulysses "echo \$DISPLAY>~/.last-display; screen -d -r"

Now, this shell alias here sets the display appropriately, so that, for example, here xterm runs xterm on your “current” display:
alias here='DISPLAY=`cat ~/.last-display`'

Related Posts: On this day...

Leave a Reply

You must be logged in to post a comment.