Pregunta sobre scripting, automation, ssh, gnu-screen – Usando la pantalla GNU de forma completamente transparente y automática.

19

La pantalla es increíble, por supuesto, pero no quiero tener que pensar en ello. A menudo acudo a una máquina, comienzo a hacer un montón de cosas y luego pienso: "Dios mío, desearía haber pensado en iniciar una sesión de pantalla antes de hacer todo eso para poder volver a conectarme a esto desde casa más tarde".

Me gustaría que la pantalla se inicie automáticamente cada vez que inicie sesión en una máquina. Y cuando me desconecto, quiero poder volver a conectarme de forma inmediata y sencilla sin tener que preocuparme con "screen -ls" y "screen -dr".

Tengo un script que implementa una solución a este problema que publicaré como respuesta. Estoy interesado en ver otros enfoques.

Tu respuesta

9   la respuesta
3

Tengo lo siguiente en mi .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

Lo encontré en línea en algún lugar hace un tiempo, no estoy seguro de dónde.

Actualizar Se corrigió el error que se señalaba en los comentarios. Gracias r. Paté

¿No es suficiente "exportar _STARTED_SCREEN = 1", en lugar de configurar y exportar? Roger Pate
@RogerPate no, en realidad era mejor antes con la primera configuración y luego con la exportación, de esa manera era realmente portátil y funcionaba en otros shells que cumplen con POSIX. Ahora es unos pocos bytes más pequeño, pero se rompería si usara, por ejemplo, un guión en lugar de bash, etc. Vea, por ejemplo,mywiki.wooledge.org/Bashism Matija Nalis
1

yo suelomosh (carcasa móvil). Mantiene su conexión activada incluso si va al modo de suspensión, se desconecta de la red, cambia la IP, etc. Cada vez que regresas, recuperas tu conexión.

7
ssh [email protected] -t 'screen -dRR'

Esto recargará / creará su sesión de pantalla al conectarse. Esto hace exactamente lo que se solicitó, incluso si transfiere la responsabilidad de generar la sesión al cliente iniciador. Idealmente, desearía algún proceso en el servidor que administre lo que se presenta a los clientes conectados. Por lo que yo sé, eso no existe. Nadie ha sugerido la solución ideal en este hilo. Para mí esto es menos "no ideal" que el resto. Sin scripts, sin errores, sin problemas de TTY, sin malas interacciones con otros comandos ssh, sin posibilidad de infinitos bucles, sin edición de archivos, no se requieren paquetes adicionales.

0

Depende de tu shell, pero ¿qué pasa con .bashrc? (Si usas bash "screen -rd")

la razón es una bomba de horquilla kevinlawler
@highperformance: ¿y qué te hace pensar que no puedes verificar .bashrc si ya estás ejecutando en pantalla? ¿También necesita una advertencia de que un café puede estar caliente? EFraim
La razón detrás de downvote es: ¿a alguien no le gusta bash? EFraim
se puede verificar, pero no es fácil hacerlo correctamente o de manera sucinta. métodos ingenuos romperán decirssh host 'echo hello world'. Ver el progreso en las otras respuestas. kevinlawler
7

En realidad, la pantalla establece la variable TERM en 'pantalla'. Así que el guión es aún más fácil. Esto es lo que yo uso:

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

Funciona como un amuleto, el-x asegura que incluso si la pantalla está unida a algún otro lugar, la adjunto aquí. De esta manera solo tengo una pantalla donde puedo hacer un seguimiento de todo.

¿Qué sucede si el usuario ejecuta "ssh hostname 'ls -R ~ / .local'", por ejemplo? Sridhar Ratnakumar
10

Ahi estaautossh el cual reconecta automáticamente las sesiones ssh desconectadas.

Viene con un script de ejemplo llamadorscreen que hace exactamente eso. Es sencillo:

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

Entonces tienes que volver a entrenar tus dedos para escribirrscreen hostname en lugar dessh hostname

1

Tal vez ponerexec screen -dr en su .login?

14

Usa lo siguiente,ssc, en lugar dessh. Si solo hacesssc remote.com"luego listará las sesiones de pantalla existentes. Déle un tercer argumento y se conectará a esa sesión de pantalla, o lo creará y se conectará a él. De cualquier manera, si se desconecta, simplemente puede hacer" flecha arriba, ingresar "en el shell para volver a conectarse. ¡Cero conocimiento de la pantalla requerido! Edit: Gracias a @klochner por extender esto para manejar opciones ssh arbitrarias. ¡Ahora puede usar esto 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\"");
}

Por cierto, hay un truco para forzar una sesión ssh para salir y devolverle el aviso de su terminal local cuando pierde la conectividad de la red:
https://superuser.com/questions/147873/ssh-sessions-in-xterms-freeze-for-many-minutes-whenever-they-disconnect

En mi sistema Ubuntu (10.4) tuve que modificar la expresión regular para tener en cuenta la información de fecha / hora que se imprime al lado de cada sesión. if (/ ^ \ s * (\ d +) \. (\ S +) \ s + (([^)] *)) \ s + (([^)] *)) /) {($ num, $ tag, $ estado) = ($ 1, $ 2, $ 4); Nathan Bell
En cuanto a que la pantalla es demasiado inteligente con su tabulación invisible y silenciosa en los nombres de pantalla, sugiero una convención de asegurarse de que cada nombre de pantalla que use comience con una letra distinta. Use una palabra descriptiva la primera vez, pero a partir de entonces puede usar solo la primera letra. dreeves
2

He utilizado autossh, me es muy útil.

Preguntas relacionadas