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.
[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
".
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"'
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.
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.
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.
This is now subsumed by this: Using GNU Screen completely transparently and automatically
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\""); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With