Автоматически (или более просто) переподключиться к сеансу экрана после прерывания сети - PullRequest
55 голосов
/ 24 января 2009

ДОБАВЛЕНО: Я полагаю, что этот вопрос теперь включен в этот вопрос: Использование GNU Screen полностью прозрачно и автоматически

Смотрите также этот связанный вопрос:
https://superuser.com/questions/147873/ssh-sessions-in-xterms-freeze-for-many-minutes-whenever-they-disconnect

Оригинальный вопрос:

Было бы неплохо, если бы существовал способ подключиться к машине по ssh и немедленно подключиться к определенной сессии экрана. Вы можете сделать это:

laptop> ssh server.com screen -ls

, и он покажет список экранов, доступных на server.com, например, [1]:

123.pts-1
456.pts-2

И тогда вы можете попытаться сделать это:

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

но это не помогает, говоря: «Должен быть подключен к терминалу». Сначала вы должны выполнить ssh, а затем выполнить «screen -dr pts-2» на server.com, что не очень хорошо, если у вас нестабильное соединение и вы часто отключаетесь. Вы хотите иметь возможность возобновить с помощью простого «ввода со стрелкой вверх» на ноутбуке. (Или, возможно, сделать его еще более автоматическим.)

У меня есть смешное решение этой проблемы, которое я опубликую в качестве ответа, и надеюсь, что оно обернется забвением в пользу Правильного пути решения этой проблемы.


Сноски:

[1] Или, лучше, если вы создали сеансы экрана с именами, такими как "screen -S foo" и "screen -S bar", тогда вы получите более дружелюбный список, например:

123.foo
456.bar

и может восстановить соединение, например, с "screen -dr foo".


Мини-урок, включающий ответ на этот вопрос:

Войдите в систему на server.com и выполните

screen -S foo 

и никогда больше не выходить из этого сеанса. Чтобы подключиться к нему из другого места, выполните

ssh -t server.com screen -dr foo

Для просмотра списка доступных экранов, к которым необходимо подключиться:

screen -ls

или, конечно же,

ssh server.com screen -ls

для удаленной проверки доступных экранов server.com.

Теперь я использую следующий псевдоним (tcsh), основанный на ответе Джейсона ниже, чтобы подключиться к именованному экрану, если он существует, или создать и подключить иначе:

alias ssc 'ssh -t \!:1 "screen -S \!:2 -dr || screen -S \!:2"'

Ответы [ 6 ]

58 голосов
/ 24 января 2009

Опция -t делает то, что вы хотите?

     -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.

Итак:

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

Кажется, это работает в моей установке.

3 голосов
/ 02 июля 2009

Это теперь относится к этому: Использование GNU Screen полностью прозрачно и автоматически


Вот скрипт, ssc, который работает так же, как и ssh, но принимает третий аргумент, чтобы указать экран для повторного подключения или имя нового экрана. Я полагаю, что этот сценарий включает все в исходном вопросе.
#!/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\"");
}
2 голосов
/ 12 марта 2009

Я работал над чем-то похожим, но не совсем понял, ваши решения решили мою проблему, поэтому вот мое предложение:

ssh -t server.com "screen -S foo -rd || screen -S foo"

Это просто пытается открыть существующий экран с именем foo и, если он не существует, создает его. Я положу это в лаунчер на моем ноутбуке, поэтому, когда беспроводная сеть выйдет, я могу просто открыть там, где остановился.

Только что заметил, что экранная оболочка по умолчанию немного слабая, поэтому улучшение, которое настраивает вашу домашнюю среду немного лучше:

ssh -t server.com "screen -S foo -rd || screen -S foo bash -l"
2 голосов
/ 24 января 2009

Используйте параметр -t для ssh, чтобы выделить терминал при непосредственном запуске команды.

laptop> ssh -t server.com screen -dr pts-2
1 голос
/ 26 ноября 2015

Если вы хотите подключиться к одному и тому же сеансу всегда, даже если он активен, отключен или еще не существует:

ssh -t user @ server screen -xR screenName

То же самое, но создайте новый сеанс, если он уже активен для другого pty:

ssh -t user @ server screen -rR screenName

1 голос
/ 06 сентября 2013

Я конвертировал это для работы в OS X .bash_profile с одним добавлением: если второй параметр не указан, он запустит сеанс «по умолчанию».

function ssc() {
    if [[ -z $2 ]]; then
        screen="default"
    else
        screen=$2
    fi
    ssh -t $1 "screen -S $screen -dr || screen -S $screen"
}
...