Reputation: 26952
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"'
Upvotes: 58
Views: 32077
Reputation: 19
If you like to connect to the same session always even it is active, detached or not exists yet:
ssh -t user@server screen -xR screenName
The same but create a new session if it is already active on some other pty:
ssh -t user@server screen -rR screenName
Upvotes: 1
Reputation: 60029
I converted this to work on OS X .bash_profile with one addition: If no 2nd parameter is given, it will start a session "default".
function ssc() {
if [[ -z $2 ]]; then
screen="default"
else
screen=$2
fi
ssh -t $1 "screen -S $screen -dr || screen -S $screen"
}
Upvotes: 1
Reputation: 26952
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\"");
}
Upvotes: 4
Reputation:
I've been working on something similar but not quite got there, your solutions have solved my problem so here's my suggestion:
ssh -t server.com "screen -S foo -rd || screen -S foo"
This just tries to open the existing screen named foo and if it doesnt exist, creates it. I'll put this in a launcher on my laptop, so when the wireless network goes I can just open where I left off.
Just noticed that the default screen shell is a bit weak, so an improvement which sets up your home environment a little better is:
ssh -t server.com "screen -S foo -rd || screen -S foo bash -l"
Upvotes: 3
Reputation: 53320
Use the -t
option to ssh to allocate a terminal while directly running a command.
laptop> ssh -t server.com screen -dr pts-2
Upvotes: 2
Reputation: 993881
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.
Upvotes: 62