SSH Automatic screen Session

When I run Loquitor, I use a server that I access with SSH (http://bitcoinshell.mooo.com). On that page, it says to use screen to get something to keep running after the SSH session ends. I had never before used screen, but I found it to be quite useful - so useful, in fact, that I installed it on my own computer and made it run automatically in my .bashrc. Well, it runs only when the shell is from SSH, not a normal terminal. I don’t want it to run automatically when the terminal is opened normally because I open far too many terminals when I’m actually on the computer, and … well, maybe it’s just because I wanted a challenge.

I looked it up. I found the answer, as always, on Stack Exchange somewhere. Apparently, SSH sets some environment variables, so just see if those are set, and you’ll know if the shell is from SSH. I did it like this:

if [ -n "$SSH_CLIENT" ] || [ -n "$SS_TTY" ]; then
    IS_SSH=true
else
    IS_SSH=false
fi

Now, I could have just put my code in the if block instead of setting a variable, but I also use that variable when determining the color of the prompt. (The colors are switched when using SSH.)

I then wrote some other code, but I later decided to move it to its own file, .bashrc_ssh. That file is executed with this block:

if "$IS_SSH" = true; then
    if [ -f ~/.bashrc_ssh ]; then
        . ~/.bashrc_ssh
    fi
fi

I could have joined those if blocks, but I thought I might want to change things later.

The basic idea of .bashrc_ssh is that each login, the IP address is looked at. If a screen session exists whose name is that IP address, join it. If not, create it. Of course, logging in twice from the same machine would both have the same session, so I then changed it a little bit. The same session will be used, but each new login gets its own window in that session. This way, something that should continue beyond the SSH session can be detached from, and then future logins can check back on it very easily. There’s no limit (that I know of) to how many times this can be done. Right now, I have x11vnc running in one of those windows, so if it ever quits, I should be able to see the error that it gave. That isn’t why I did that, but … well, it’s an advantage I guess. Anyway, here it is (my .bashrc_ssh):

# If screen is already running, $STY will be set. We will create a new window,
# therefore, only if $STY is not set.
if [ -z $STY ]; then
    read -r client_ip _ <<< "$SSH_CLIENT"

    screen -xR "$client_ip" -p +
fi

You may wonder why I don’t run anything unless the shell is not already in a screen session. This is because each new window in a screen session reads the bashrc. Since environment variables are kept, it still looks like we’re coming from SSH, so this would run and create a new screen window, which creates another one, … I added that later than I might have.

The -x argument means to join a session that may already be attached to a terminal. The -R option means to create the session if it doesn’t exist. The -p option is for specifying which window to join in the session. Giving it + means to create a new one.

If I ever don’t want to run something in the screen session, simply hitting Ctrl-D takes me back to normal SSH. Of course, this means that any time I do want screen, I need to hit Ctrl-D an extra time. I’m still considering how to fix that, but I’m pretty happy with what I have anyway.

Written on March 13, 2017