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".