Pergunta sobre gnu-screen, automation, scripting, ssh – Usando o GNU Screen de forma totalmente transparente e automática

19

A tela é incrível, é claro, mas eu não quero ter que pensar nisso. Muitas vezes eu ssh para uma máquina, começo a fazer um monte de coisas, e então penso "Puxa, eu gostaria de ter pensado em iniciar uma sessão de tela antes de fazer tudo isso para que eu pudesse me reconectar com isso de casa mais tarde".

Eu gostaria de ter tela automaticamente iniciada sempre que eu fizer login em uma máquina. E quando eu for desconectado, quero ser capaz de imediatamente e simplesmente reconectar sem mexer em "screen -ls" e "screen -dr".

Eu tenho um script que implementa uma solução para este problema que vou postar como resposta. Estou interessado em ver outras abordagens.

Sua resposta

8   a resposta
10

autossh que reconecta automaticamente ssh-sessions desconectadas.

Ele vem com um script de exemplo chamadorscreen que faz exatamente isso. É simplesmente:

#!/bin/sh
autossh -M 0 -t $1 "screen -e^Aa -D -R"

Então você tem que treinar seus dedos para digitarrscreen hostname ao invés dessh hostname

1

mosh (concha móvel). Ele mantém sua conexão ativada mesmo se você entrar no modo de suspensão, desconectar-se da rede, alterar o IP e assim por diante. Sempre que você retorna, você obtém sua conexão de volta.

7

screen'. Então o roteiro é ainda mais fácil. Aqui está o que eu uso:

if [ "$TERM" != "screen" ]; then
  screen -xRR
fi

Funciona como um encanto, o-x garante que, mesmo que a tela esteja conectada em algum outro lugar, eu me conecto a ela aqui. Desta forma, eu só tenho uma tela onde posso acompanhar tudo.

E se o usuário executar "ssh hostname 'ls -R ~ / .local'", por exemplo? Sridhar Ratnakumar
1

exec screen -dr no seu .login?

14

Use o seguinte,ssc, ao invés dessh. Se você acabou de fazer "ssc remote.com"então ele listará as sessões de tela existentes. Dê a ele um terceiro argumento e ele se conectará a essa sessão de tela ou crie-o e conecte-se a ele. De qualquer maneira, se você for desconectado, basta fazer" seta para cima, entrar " O shell para reconectar Conhecimento zero de tela necessário Editar: Graças ao @ klochner para estender isso para lidar com opções arbitrárias ssh Agora você pode usar isso como ssh!

#!/usr/bin/env perl
# Use 'ssc' (this script) instead of 'ssh' to log into a remote machine.
# Without an argument after the hostname it will list available screens.
# Add an argument after the hostname 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.

# ssh option parsing by @klochner
my $optstring = ""; 
while ($val = shift) {
  if    ($val =~ /^-\w$/)  { $optstring .= " ".$val.(shift); }
  elsif ($val =~ /^-\w+$/) { $optstring .= " ".$val;         }
  elsif ($machine)         { $tag        =     $val;         }
  else                     { $machine    =     $val;         }
}

if (!$machine) {
  print "USAGE: ssc [ssh options] remote.com [screen name]\n";
} elsif (!$tag) {
  @screens = split("\n", `ssh $optstring $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"; }
      # remember anything weird about the screen, like shared screens
      if($status =~ /^(attached|detached)$/i) { 
        $special{"$num.$tag"} = "";
      } else {
        $special{"$num.$tag"} = "[$status]";
      }
    }
  }
  print "ATTACHED:\n";
  for(sort { ($a=~/\.(\w+)/)[0] cmp ($b=~/\.(\w+)/)[0] } keys(%att)) {
    ($tag) = /\.(\w+)/;
    print "  $tag\t($_)\t$special{$_}\n" if $att{$_};
  }
  print "DETACHED:\n";
  for(sort { ($a=~/\.(\w+)/)[0] cmp ($b=~/\.(\w+)/)[0] } keys(%att)) {
    ($tag) = /\.(\w+)/;
    print "  $tag\t($_)\t$special{$_}\n" unless $att{$_};
  }
} else {
 system("ssh $optstring -t $machine \"screen -S $tag -dr || screen -S $tag\"");
}

Btw, há um truque para forçar uma sessão ssh a sair e retornar seu prompt de terminal local quando você perder a conectividade de rede:
https://superuser.com/questions/147873/ssh-sessions-in-xterms-freeze-for-many-minutes-whenever-they-disconnect

No meu sistema Ubuntu (10.4) eu tive que modificar a expressão regular para considerar as informações de data / hora que são impressas ao lado de cada sessão. if (/ ^ \ s * (\ d +) \. (\ S +) \ s + (([^)] *)) \ s + (([^)] *)) /) {($ num, $ tag, $ status) = ($ 1, $ 2, $ 4); Nathan Bell
Quanto a tela sendo muito inteligente com sua conclusão de tabulação invisível e silenciosa nos nomes de tela, sugiro uma convenção de certificar-se de que cada nome de tela que você usa comece com uma letra distinta. Use uma palavra descritiva na primeira vez, mas a partir de então você pode usar apenas a primeira letra. dreeves
0

screen -rd")

você pode verificar, mas não é fácil fazer corretamente ou sucintamente. métodos ingênuos vão quebrar dizerssh host 'echo hello world'. veja o progresso nas outras respostas. kevinlawler
A razão por trás do downvote é: alguém não gosta de bash? EFraim
a razão é uma bomba garfo kevinlawler
@highperformance: e o que faz você pensar que não pode fazer check-in do .bashrc se já estiver executando na tela? Você também precisa de um aviso de que um café pode estar quente? EFraim
3

Eu tenho o seguinte no meu .bashrc

 if [ "$PS1" != "" -a "${_STARTED_SCREEN:-x}" = x -a "${SSH_TTY:-x}" ] 
 then 
     export _STARTED_SCREEN=1;
     sleep 1 
     screen -RR && exit 0 
     # normally, execution of this rc script ends here... 
     echo "Screen failed! continuing with normal bash startup" 
 fi

Eu encontrei on-line em algum lugar há algum tempo, não tenho certeza onde.

Atualizar Corrigido erro que foi apontado nos comentários. Obrigado R. Pate

Não é "exportar _STARTED_SCREEN = 1" o suficiente, em vez de definir, em seguida, exportar? Roger Pate
@RogerPate Não, na verdade foi melhor antes com a primeira configuração e depois com a exportação - dessa forma, era realmente portátil e funcionava em outros shells compatíveis com POSIX. Agora são alguns bytes menores, mas quebrariam se você usasse por exemplo traço em vez de bash, etc. Veja por exemplomywiki.wooledge.org/Bashism Matija Nalis
7
ssh [email protected] -t 'screen -dRR'

atamente o que foi solicitado, mesmo que mova a responsabilidade de gerar a sessão para o cliente iniciante. O ideal seria que você desejasse algum processo no servidor para gerenciar o que é apresentado aos clientes conectados. Tanto quanto sei, isso não existe. Ninguém sugeriu a solução ideal neste segmento. Para mim, isso é menos "não ideal" do que o resto. Sem scripts, sem bugs, sem problemas TTY, sem interações ruins com outros comandos ssh, sem potencial para loops infinitos, sem edição de arquivos, sem necessidade de pacotes adicionais.

Perguntas relacionadas