How to effectively use screen and SSH?

I just did the following for all of my servers so that when I connect via SSH I am automatically put into a Screen session.

Add the following to the ~/.bashrc for your user accounts:

# Auto-screen invocation. see: http://taint.org/wk/RemoteLoginAutoScreen
# if we're coming from a remote SSH connection, in an interactive session
# then automatically put us into a screen(1) session.   Only try once
# -- if $STARTED_SCREEN is set, don't try it again, to avoid looping
# if screen fails for some reason.
if [ "$PS1" != "" -a "${STARTED_SCREEN:-x}" = x -a "${SSH_TTY:-x}" != x ] 
then
  STARTED_SCREEN=1 ; export STARTED_SCREEN
  screen -RR -S main || echo "Screen failed! continuing with normal bash startup"
fi
# [end of auto-screen snippet]

This will start a screen session named main if it doesn't exist or reconnect to it if it does. This was done because I have several other screen sessions running detached for various services and didn't want to connect to them.


I have the following in my .bash_profile on my remote servers:

if [ -z "${STY}" -a -t 0 -a X${USER} = Xarcege ]; then
    reattach() {
        if [ -n "${SSH_AUTH_SOCK}" ]; then
            ln -snf "${SSH_AUTH_SOCK}" "${HOME}/.ssh/agent-script"
            SSH_AUTH_SOCK="${HOME}/.ssh/agent-script" export SSH_AUTH_SOCK
        fi
        exec screen -A -D -RR ${1:+"$@"}
    }
    screen -wipe
    echo 'starting screen... (type Ctrl-C to abort)'
    sleep 5 && reattach
fi

This does two things: first, sets up a shell function to replace the shell and carry forward the ssh-agent connection, second it calls the function after pausing for a few seconds (in case you don't want screen to start).

The first if clause will be true if not already running screen (-z "${STY}") is attached to a terminal (-t 0) and I'm not running sudo (which sometimes doesn't change $USER).

The reattach function will first check if ssh was called with an ssh-agent port active (-n "${SSH_AUTH_SOCK}"). Then it will replace whatever is at ~/.ssh/agent-script with the currently active socket file and replace the environment variable ($SSH_AUTH_SOCK) with the new value. Then the script will replace the current shell with a single screen session (making sure that only one should exist). Any arguments to the reattach function are passed to the command (${1:+"$@"}).

The last part first removes any dead sessions (screen -wipe), lets the user (me) know that screen will be starting shortly and can instead return to the shell by pressing Ctrl-C. Then it waits for 5 seconds and calls the reattach function.


First, if you use byobu you can configure a new shell session to always automatically start byobu (which is essentially a nice screen configuration, although newer versions may use tmux as the backend). If you really don't want byobu then you can probably set screen to connect manually by editing your .profile or other shell config script to exec screen if TERM != "screen".

If you don't like that, you can use the authorized_keys file to run a specific command for connections with a specific key (and you can have as many keys as you like). See man sshd for details. I'd suggest you make the command run a script that checks if screen is running and connects, or else starts a new session.

As for disconnect on Ctrl-D, screen allows you to set up key mappings in your .screenrc. See man screen for details. You're looking for "bindkey".

Tags:

Ssh

Gnu Screen