20050925 Screen Cheat Sheet
===========================
by David Baird

What does screen do?
--------------------

Screen multiplexes multiple virtual terminals to a single screen.  This
means that from a single xterm, you can be running multiple shells and
easily switch between them.  I use screen for the following applications
(with the help of the shell functions listed at the end of this article):

    - managing a large number of text editing sessions
    - doing system administration on multiple computers
    - managing multiple BitTorrent downloads
    - managing persistent tasks, such as running fetchmail, starting
      custom servers, setting up ssh tunnels

Another benefit of screen is that it can allow you to work in multiple
locations across a network.  If you keep your work contained inside
of screen, you can easily detach from the screen, move to some other
location, ssh back into your computer, and re-attach to the original
screen session, and resume your work.

Screen also reduces the number of xterms needed to get jobs done.

From the shell
--------------

screen -ls
screen -S <session-name> # create new session (remember: type a capital "S")
screen -x <session-name-or-prefix> # attach to session
    Example: if you have a screen named "math591" and it is the only
    screen that begins with "math" then you can type either of the
    following commands to attach:

    screen -x math591
    screen -x math

screen -wipe # wipe dead screens

From screen
-----------
Everything is case sensitive!  'C-a F' means capital 'F': don't type 'f'.
'C-' means press the <Ctrl>.

C-a ? # see a list of all the commands
C-a c # create a new window
C-a A # rename the current window
C-a " # show a list of windows
C-a d # detach from the current session
C-a x # lock the current screen process (requires password to unlock)

Trouble / problems
-------------------

If you cannot type because screen appears to be frozen or deadlocked,
then the reason is you quite possibly pressed an xoff key (C-a s, or
C-s) by accident.  One of these functions should provide a cure (try
both of them!):

    C-a q # send xon to screen window
    C-q # send other xon to terminal

    C-a F # adjust the virtual size of the screen to fit your current terminal

Do not start screen sessions within screen sessions unless you are also
the type of person who likes looking at diffs of diffs (of diffs).  If
you need to detach from a screen within a screen, type:

    C-a a d

To determine if you currently inside of a screen, try this command:

    echo $TERM

If the result prints "screen", then you are probably inside of a screen.


Advanced features from the shell
--------------------------------
screen -d -m -S <session-name>
    Start a new screen, but do not attach to it.

screen -S <session-name> -X quit
    Kill a screen session.

screen -ls | egrep -e "[0-9]+\.<session-name>[[:space:]]" && <some-command>
    See if a screen with <session-name> exists and then execute
    <some-command> if the screen does exist.

screen -ls | egrep -e "[0-9]+\.<session-name>[[:space:]]" || <some-command>
    (alternate version of the above).  Execute <some-command> if the
    screen with <session-name> does not exist.

screen -S <session-name> -p <window-name> -X stuff "<some-text>"
    Send <some-text> to a specific window of a specific screen session.
    Hint: to send an end-of-line character, type 'C-v C-M', and most
    programs will display the text '^M' to represent this character.

Example functions for managing vim
-----------------------------------

Into ~/.aliases-screen, paste the following code.  NOTE: inside the
"screen-send-line" function, you must type 'C-v C-M' to generate the
'^M'.  Do not type '^' then 'M'.

    #!/bin/bash

    function screen-new-session() {
        # Usage: screen-new-session session-name
        screen -d -m -S $1
    }

    function screen-kill-session() {
        # Usage: screen-kill-session session-name
        screen -S $1 -X quit || echo Failed to kill session "$1"
    }

    function screen-guarantee-session() {
        # Usage: screen-guarantee session-name
        screen -ls | grep -i '(dead' && screen -wipe
        screen -ls | egrep -e "[0-9]+\.${1}[[:space:]]" || screen-new-session $1
    }

    function screen-new-window() {
        # Usage: screen-new-window session-name window-name
        screen -S "$1" -X screen -t "$2"
        # FIXME: when involing -X screen -t "$2", some crazy tty settings
        # get put in place (backspace kills lines instead of backspacing)
        screen-send-line "$1" "$2" "stty sane; bash; exit"
    }
     
    function screen-get-current-window() {
        # Usage: screen-get-current-window
        # stdout := name of current window
        screen -S "$1" -X screen -t "$2"
    }
     
    function screen-send-line() {
        # Usage: screen-send-line session-name window-name line
        screen -S "$1" -p "$2" -X stuff "${3}^M"
    }

    function v() {
        # Usage:
        # v - attach to the v screen
        # v <filename> - edit filename in a v screen
        screen-guarantee-session v
        if [ "$*" != "" ]; then
            pushd `dirname $*`
            dir=`pwd`
            popd
            basename=`basename $*`
            echo "$basename" "$dir" >> ~/.v_history
            window="$basename $dir"
            screen-new-window v "$window"
            screen-send-line v "$window" "cd \"`pwd`\""
            screen-send-line v "$window" "vim \"$*\""
        fi
        echo $TERMCAP | grep screen > /dev/null &&
            echo 'You are inside of a screen' ||
            screen -x v -p "$window"
    }

Into ~/.bashrc, paste the following code:

    . ~/.screen-aliases