Running programs on a remote machine in an ssh session is convenient, but has a few downsides. First, if the connection drops (Internet outage at either end, firewall reconfiguration, or other network problem), the running program is frequently killed. Second, you no longer have the freedom to shut down or move the ssh client laptop; if it moves to a new address, we lose the program on the server as well.

We can fix both of these by running apps on the server(s) inside screen, a utility included in Linux, Mac OS, and other unixes (and available on Windows with the Cygwin add-on). The screen program grabs the program output and remembers it even when the ssh connection has gone away for either of these reasons, showing it to us again when we reconnect. This allows the user to start a program, run it for a while, disconnect entirely from the server, shut down her laptop, and reconnect when she gets home. The program on the server doesn't even notice that the user temporarily disappeared.


screen on each server

You'll need to have the screen program installed on each server. To see if it's already on the server, run this from your client:

ssh myserver 'which screen'

If this returns a path to the screen program you're all set; otherwise run:

ssh -t myserver 'sudo apt-get install screen || sudo yum -y install screen'

While you certainly can have screen on your client system and it can be quite useful on the client end too, it's not required for this.

connect script "to" on client

This script sets up the connection and sets a title for your local window when possible. Pick a directory in your path and save the following lines to the file to in that directory:

echo -ne "\033]0;${1}: ${2}\007"
ssh -t "$1" screen -S "${2:-DefaultScreen}" -d -R

Now make the script executable with:

chmod 755 /script/directory/to

Try it!

Instead of running ssh myserver, run:

to myserver

If you've set up ssh keys already, this will put you in a shell just like ssh did. (Note: if you're still using a password for ssh, you'll be prompted for it. This would be a great time to switch over to ssh keys for the convenience and security.)

Here you can start up anything you could have with ssh. To test it, run this command:

while sleep 5 ; do date ; done

Let this output a few lines, then let's disconnect with Ctrl-a, then d. This tells the screen program on the server that you're exiting, and the ssh connection that got you there will close down too. The screen program will continue to run on the server, running the date program every 5 seconds. Wait for 15 seconds or so, then reconnect with the same to myserver command you used above. When you're back, notice that there are more date output lines than when you started; the screen program caught them and remembered them while you were disconnected. You can disconnect with Ctrl-a, d and reconnect with to myserver as often as you'd like and the program will keep running. You can even disconnect, shut down your laptop, move to a totally different network, start back up again with a new IP address, and reconnect - screen and the programs you run in it won't notice.

Disconnect with Ctrl-a, d when you're done.

Multiple sessions on a server

You can even have multiple screens running on a single server. Pick a name for a new session, one that describes what you intend to run in it. In this example I want to run top and be able to disconnect and reconnect. I'll call the session monitoring and start it up with:

to myserver monitoring

Instead of connecting to your old session that was running date every 5 seconds, you get a fresh command prompt. Run top in it and test that you can disconnect like above. Once you're back to your laptop, connect to the original session with:

to myserver

You should be looking at the date output again. This lets you switch back and forth between as many sessions as you'd like by giving them different names. For reference, our first screen session actually does have a name: "DefaultScreen", since we didn't include one following to myserver.

Sharing a screen session...

...in multiple windows as the same user

Let's say you want the output from a single command to show up in multiple terminal windows; perhaps you're doing a demo of a tool and want to see it on multiple (non-mirrored) monitors.

First, create the screen session on the server that will host it with:

screen -S screen_name -R

(don't use the "to" script with any of these sharing approaches; "to" kicks off anyone that has that screen session open, which is not what we want.)

Start a program to watch there, say, "top".

Now ssh to the server if you're not already on it and connect with the "-x" parameter:

ssh server_name
screen -x screen_name

You should instantly see the "top" program you started. Any keystrokes you type in either window are fed to the program immediately. If you type "M" in one window top will sort by memory usage; if you then type "P" in the other window it will sort by processor usage.

...between multiple users

Lets say two different users - lisa and bart - want to see the same output. The steps are similar, but the user that starts the screen window needs to give permission to the second user before they can connect. One bit of housekeeping; as root or under sudo, run this once (and after the screen package is updated in the future):

sudo chmod u+s $(which screen)

Now, create the screen session as lisa:

screen -S screen_name -R

In that window, you'll need to type the following:

ctrl-a:multiuser onEnter
ctrl-a:acladd bartEnter

At this point bart can connect with:

screen -x lisa/screen_name

Keep in mind that bart now has access to a terminal that's logged in as lisa, and can type any commands that lisa has rights for. Good thing bart never misbehaves.

...between multiple users, but making the other users read-only

To let other users see what you're doing but not give them access to type anything, we have to do two things. First, we have to block bart from writing to this specific terminal:

ctrl-a:aclchg bart -w "#"Enter

Now, we have to block bart from most of the features of screen, or else he could simply create a new window, in which he regains write privileges. The first command below strips bart of all access, then the second command gives him back minimal abilities:

ctrl-a:aclchg bart -x "?"Enter
ctrl-a:aclchg bart +x "colon,wall,detach"Enter

If lisa is hosting multiple users and wants to make them all read-only:

ctrl-a:aclchg * -w "#"Enter
ctrl-a:aclchg * -x "?"Enter
ctrl-a:aclchg * +x "colon,wall,detach"Enter

All of the above restrictions and sharing commands should be run before you give bart or other users access to this machine.

Additional notes