2009-07-02 16 views
19

Lo schermo è sorprendente, ovviamente, ma non voglio pensarci. Spesso faccio un ssh su una macchina, comincio a fare un sacco di cose e poi penso "Accidenti, vorrei aver pensato di avviare una sessione di schermate prima di fare tutto ciò in modo da potermi riconnettere da casa più tardi".Utilizzo dello schermo GNU in modo completamente trasparente e automatico

Mi piacerebbe avere lo schermo automaticamente avviato ogni volta che accedo a un computer. E quando mi disconnetto, voglio essere in grado di ricollegarmi immediatamente e semplicemente senza preoccuparmi di "screen -ls" e "screen -dr".

Ho uno script che implementa una soluzione a questo problema che pubblicherò come risposta. Sono interessato a vedere altri approcci.

risposta

14

Utilizzare quanto segue, ssc, anziché ssh. Se si esegue semplicemente "ssc remote.com", verranno elencate le sessioni dello schermo esistenti. Dagli un terzo argomento e si collegherà a quella sessione dello schermo, oppure crearla e connettersi ad essa. In entrambi i casi, se ti disconnetti, puoi semplicemente fare "freccia su, immettere" nella shell per riconnetterti. Necessaria conoscenza dello schermo! Modifica: grazie a @klochner per estendere questo per gestire le opzioni ssh arbitrarie. Ora puoi usarlo proprio come 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, c'è un trucco per forzare una sessione ssh per uscire e dare di nuovo il prompt del terminale locale quando si perde la connettività di rete:
https://superuser.com/questions/147873/ssh-sessions-in-xterms-freeze-for-many-minutes-whenever-they-disconnect

+1

Per quanto lo schermo sia troppo intelligente con il suo completamento invisibile e silenzioso delle tabulazioni sui nomi delle schermate, suggerisco una convenzione per assicurarmi che ogni nome di schermo che usi inizi con una lettera distinta. Usa una parola descrittiva la prima volta ma da quel momento in poi puoi usare solo la prima lettera. – dreeves

+0

Sul mio sistema Ubuntu (10.4) ho dovuto modificare l'espressione regolare per tenere conto delle informazioni sulla data/ora che stampa accanto a ciascuna sessione. if (/^\ s * (\ d +) \. (\ S +) \ s + \ (([^ \)] *) \) \ s + \ (([^ \)] *) \) /) { ($ num, $ tag, $ stato) = ($ 1, $ 2, $ 4); –

0

Dipende dalla shell, ma per quanto riguarda .bashrc? (Se si usa "schermo -rd" bash)

+0

Il motivo alla base di downvote è: a qualcuno non piace bash? – EFraim

+2

il motivo è un fork bomba – kevinlawler

+2

@highperformance: e cosa ti fa pensare che non puoi effettuare il check in .bashrc se sei già in esecuzione sullo schermo? Hai anche bisogno di un avvertimento che un caffè potrebbe essere caldo? – EFraim

1

Forse mettere exec screen -dr nella tua .login?

3

Ho il seguente nel mio .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 

ho trovato on-line da qualche parte un po 'fa, non so dove.

Aggiornamento Errore fisso che è stato segnalato nei commenti. Grazie R. Pate

+1

Non è sufficiente "export _STARTED_SCREEN = 1", anziché impostare quindi esportare? –

+0

@RogerPate no, in realtà era meglio prima con la prima impostazione e poi l'esportazione - in quel modo era effettivamente portatile, e funzionava su altre shell conformi a POSIX. Ora sono pochi byte più piccoli, ma si interromperanno se si usa per esempio un trattino invece di bash, ecc. Vedi ad esempio http://mywiki.wooledge.org/Bashism –

7

In realtà lo schermo imposta la variabile TERM su "schermo". Quindi la sceneggiatura è ancora più semplice. Ecco quello che io uso:

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

funziona come un fascino, la -x assicura che, anche se lo schermo è attaccato da qualche altra parte io attribuisco a qui. In questo modo ho solo uno schermo in cui posso tenere traccia di tutto.

+0

Cosa succede se l'utente esegue "ssh hostname 'ls -R ~ /.local '", ad esempio? –

9

c'è autossh che ricollega automaticamente sessioni ssh disconnesse.

Viene fornito con uno script di esempio chiamato rscreen che fa esattamente questo.Si tratta, semplicemente:

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

Poi si deve riqualificare le dita per digitare rscreen hostname invece di autossh ssh hostname

2

ho usato, è molto utile per me

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

Questo ricaricherà/crea la tua sessione sullo schermo per la connessione. Questo fa esattamente ciò che è stato richiesto, anche se trasferisce la responsabilità della generazione della sessione al client di avvio. Idealmente vorrai qualche processo sul server che gestisca ciò che viene presentato ai client di connessione. Per quanto ne so, questo non esiste Nessuno ha suggerito la soluzione ideale in questa discussione. Per me questo è meno "non ideale" rispetto al resto. Niente script, niente bug, niente problemi TTY, nessuna interazione negativa con altri comandi ssh, nessuna possibilità di loop infiniti, nessuna modifica di file, nessun pacchetto aggiuntivo richiesto.

1

Io uso mosh (mobile shell). Mantiene la connessione anche se si passa alla modalità sospensione, si disconnette dalla rete, si modifica l'IP e così via. Ogni volta che ritorni, ottieni la tua connessione.

Problemi correlati