Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically (or more easily) reconnect to a screen session after network interruption

ADDED: This question is now, I believe, subsumed by this one: Using GNU Screen completely transparently and automatically

See also this related question:
https://superuser.com/questions/147873/ssh-sessions-in-xterms-freeze-for-many-minutes-whenever-they-disconnect

Original question:

It would be nice if there were a way to ssh to a machine and immediately reconnect to a specific screen session. You can do this:

laptop> ssh server.com screen -ls 

and it will show a list of screens available on server.com like so [1]:

123.pts-1 456.pts-2 

And then you might try to do this:

laptop> ssh server.com screen -dr pts-2 

but that fails, saying "Must be connected to a terminal." You have to ssh in first and then do the "screen -dr pts-2" on server.com which is no good if you have a flaky connection and get disconnected a lot. You want to be able to resume with a simple "up-arrow enter" on the laptop. (Or perhaps make it even more automatic.)

I have a rihackulous solution to this problem which I'll post as an answer and hope it gets downvoted to oblivion in favor of the Right Way to deal with this.


Footnotes:

[1] Or, better, if you created the screen sessions with names like "screen -S foo" and "screen -S bar" then you'll get a friendlier list like:

123.foo 456.bar 

and can reconnect with, eg, "screen -dr foo".


Mini screen tutorial, incorporating the answer to this question:

Login in to server.com and do

screen -S foo  

and then never log out of that session again. To reconnect to it from elsewhere, do

ssh -t server.com screen -dr foo 

To list available screens to reconect to:

screen -ls 

or, of course,

ssh server.com screen -ls 

to check on server.com's available screens remotely.

I now use the following alias (tcsh), based on Jason's answer below, to connect to a named screen if it exists or create and connect otherwise:

alias ssc 'ssh -t \!:1 "screen -S \!:2 -dr || screen -S \!:2"' 
like image 819
dreeves Avatar asked Jan 23 '09 22:01

dreeves


People also ask

How do I reconnect to a screen session?

To start a screen session, you simply type screen within your ssh session. You then start your long-running process, type Ctrl+A Ctrl+D to detach from the session and screen -r to reattach when the time is right.

How do I keep a session alive in Linux?

When you log in to the server, the terminal session won't automatically close. Instead, the configuration file will keep sending the alive signal after the specific interval set in the configuration file to keep the terminal session alive.


2 Answers

Does the -t option do what you want?

      -t      Force pseudo-tty allocation.  This can be used to execute arbi-              trary screen-based programs on a remote machine, which can be              very useful, e.g. when implementing menu services.  Multiple -t              options force tty allocation, even if ssh has no local tty. 

So:

laptop> ssh -t server.com screen -dr pts-2 

This seems to work in my installation.

like image 114
Greg Hewgill Avatar answered Sep 21 '22 15:09

Greg Hewgill


This is now subsumed by this: Using GNU Screen completely transparently and automatically


Here's a script, ssc, that works just like ssh but takes a third argument to specify the screen to reconnect to, or the name of a new screen. I believe this script subsumes everything in the original question.
#!/usr/bin/env perl # Use 'ssc' (this script) instead of 'ssh' to log into a remote machine. # Without a 3rd argument it will list available screens. # Give it a 3rd argument to attach to an existing screen or specify a new #   screen.  Eg, ssc remote.com foo # The numbers in front of the screen tag can usually be ignored. # Screen is a little too clever though in that if there's an existing screen "bar" #   and you say "ssc remote.com b" it will reconnect you to "bar" instead of making #   a new screen "b".  It's like invisible and silent tab-completion.  if(scalar(@ARGV)==0 || scalar(@ARGV) > 2) {   print "USAGE: ssc remote.com [screen name]\n"; } elsif (scalar(@ARGV) == 1) {   $machine = shift;   @screens = split("\n", `ssh $machine screen -ls`);   for(@screens) {     if(/^\s*(\d+)\.(\S+)\s+\(([^\)]*)\)/) {       ($num, $tag, $status) = ($1, $2, $3);       if($status =~ /attached/i) { $att{"$num.$tag"} = 1; }       elsif($status =~ /detached/i) { $att{"$num.$tag"} = 0; }       else { print "Couldn't parse this: $_\n"; }     }   }   print "ATTACHED screens:\n";   for(keys(%att)) { print "  $_\n" if $att{$_}; }   print "DETACHED screens:\n";   for(keys(%att)) { print "  $_\n" unless $att{$_}; } } else {   $machine = shift;   $tag = shift;   system("ssh -t $machine \"screen -S $tag -dr || screen -S $tag\""); } 
like image 28
dreeves Avatar answered Sep 23 '22 15:09

dreeves