Come uccidere la sessione SSH che è stata avviata con l'opzione -f (eseguita in background)


50

Sono piuttosto perso su questo. Dalla pagina man:

 -f      Requests ssh to go to background just before command execution.

Dopo aver avviato SSH con l' -fopzione, ho un tunnel funzionante. Ma dopo aver finito di usarlo non so come interagire ulteriormente con esso. Ad esempio, non riesco a chiudere il tunnel SSH quando finisco con esso.

I soliti metodi che conosco non funzionano. Ad esempio, jobsnon restituisce nulla. Il ~comando non è riconosciuto (e non so esattamente come usarlo, comunque).

Tuttavia, pgrepmi dice che il tunnel SSH è ancora in esecuzione (dopo aver chiuso il terminale, ecc.). Come interagisco con esso? Come lo chiudo?

Risposte:


65

Una soluzione particolarmente buona per gli script è l'uso master mode, con un socket per i comandi di controllo:

ssh -f -N -M -S <path-to-socket> -L <port>:<host>:<port> <server>

Per chiuderlo di nuovo:

ssh -S <path-to-socket> -O exit <server>

Ciò evita sia il grepping per gli ID di processo sia eventuali problemi di temporizzazione che potrebbero essere associati ad altri approcci.


10
Solo per espandere un po 'per i non iniziati, <path-to-socket> è un percorso di un file che l'istanza principale del client ssh creerà per la comunicazione tra processi con altre istanze del client ssh che vogliono condividere la connessione dell'istanza principale. Il file creato rappresenterà effettivamente un socket di dominio unix. Può essere nominato e localizzato come e dove vuoi, ad es. /tmp/session1(Anche se si consiglia di nominarlo usando % pattern - vedi la descrizione di ControlPath in man ssh_config)
golem

1
Inoltre sembra che la parte <server> del ssh -S <path-to-socket> -O exit <server>comando possa essere qualsiasi stringa, ma deve essere presente. È un po 'goffo.
Golem,

1
Questa risposta e questa domanda sono piuttosto vecchie, ma ho voluto approvare questo come probabilmente il modo più elegante e "corretto" di gestire questo problema che ho visto. Grazie Signore!
zentechinc,

41

Ho trovato la soluzione qui: http://www.g-loaded.eu/2006/11/24/auto-closing-ssh-tunnels/

Il modo migliore: tunnel che si chiudono automaticamente

Come è stato menzionato in precedenza, invece di utilizzare la combinazione di switch -f -N, possiamo semplicemente usare -f da solo, ma anche eseguire un comando sul computer remoto. Ma quale comando deve essere eseguito, dato che dobbiamo solo inizializzare un tunnel?

Questo è quando il sonno può essere il comando più utile di tutti! In questa particolare situazione, il sonno ha due vantaggi:

  • non fa nulla, quindi nessuna risorsa viene consumata
  • l'utente può specificare per quanto tempo verrà eseguito

Di seguito viene spiegato come questi aiuti nella chiusura automatica del tunnel SSH.

Iniziamo la sessione ssh in background, mentre eseguiamo il comando sleep per 10 secondi sul computer remoto. Il numero di secondi non è cruciale. Allo stesso tempo, eseguiamo vncviewer esattamente come prima:

[me@local]$ ssh -f -L 25901:127.0.0.1:5901 me@remote.example.org sleep 10; \
          vncviewer 127.0.0.1:25901:1

In questo caso, al client ssh viene richiesto di eseguire il fork della sessione ssh in background (-f), creare il tunnel (-L 25901: 127.0.0.1: 5901) ed eseguire il comando sleep sul server remoto per 10 secondi (sleep 10).

La differenza tra questo metodo e quello precedente (switch -N), sostanzialmente, è che in questo caso l'obiettivo principale del client ssh non è quello di creare il tunnel, ma piuttosto di eseguire il comando sleep per 10 secondi. La creazione del tunnel è una sorta di effetto collaterale, un obiettivo secondario. Se vncviewer non fosse utilizzato, il client ssh sarebbe uscito dopo il periodo di 10 secondi, poiché non avrebbe più lavoro da fare, distruggendo il tunnel allo stesso tempo.

Durante l'esecuzione del comando sleep, se un altro processo, in questo caso vncviewer, inizia a utilizzare quel tunnel e lo mantiene occupato oltre il periodo di 10 secondi, quindi, anche se il client ssh termina il suo lavoro remoto (esecuzione del sonno), non può uscita perché un altro processo occupa il tunnel. In altre parole, il client ssh non può distruggere il tunnel perché dovrebbe uccidere anche vncviewer. Quando vncviewer smette di usare il tunnel, anche il client ssh esce, poiché ha già raggiunto il suo obiettivo.

In questo modo, nessun processo ssh viene lasciato in esecuzione in background.


4
Una breve osservazione / correzione: per quanto ne so, devi specificare vncviewer 127.0.0.1::25091come stai usando la sintassi della porta e non la sintassi del display.
Christian Wolf,

Questa è un'ottima idea, e chiaramente i passaggi secondari di un problema che ho avuto su Windows. Le versioni recenti di Windows vengono fornite con un client SSH e in teoria supporta l'opzione -S, ma non sembra funzionare per me.
Keeely

9

Per uccidere il tunnel, utilizzare ps -C ssho ps | grep ssho qualsiasi altra variante per determinare quale processo ssh sta eseguendo il tunnel. Quindi uccidilo.

In alternativa, puoi cercare il processo determinando quale ha questa porta aperta:

netstat -lnpt | awk '$4 ~ /:1234$/ {sub(/\/.*/, "", $7); print $7}'

Se vuoi uccidere tutti i client SSH in esecuzione sul tuo computer (come utente), pkill sshlo farà.


6

Come hanno risposto gli altri qui, lo pkill sshuccide.

Per creare un tunnel che potrebbe essere ripristinato, lo avvio screensenza l' -fopzione, quindi rimuovo lo schermo con Ctrl-A D. Per riportare il tunnel, chiama screen -r.


Forza bruta, ma efficace
mafrosi il

1
Fai attenzione se ti colleghi in remoto. pkill ssh ucciderà persino la tua connessione attuale.
Kennyut,

@kennyut Ancora un altro motivo da usare screen.
Haotian Yang,

0

Quando avvio un tunnel con:

ssh -fN -D 8080 SOME_IP_HERE -l LOGIN_NAME_HERE
  • -f Richiede ssh per passare in background appena prima dell'esecuzione del comando.
  • -NNon eseguire un comando remoto. Questo è utile solo per il forwarding delle porte.
  • -D Specifica un port forwarding "dinamico" locale a livello di applicazione.
  • -l Specifica l'utente per accedere come sul computer remoto.

Posso chiuderlo con:

ps -lef | grep ssh | grep "8080" | awk "{print \$2}" | xargs kill

-1

La migliore soluzione che ho trovato per uccidere tutti i tunnel in una riga di comando è

ps -lef|grep ssh|grep "\-L"|awk '{print $4}'|xargs kill

per le sessioni ssh, basta rimuovere l'opzione tunnel

ps -lef|grep ssh|awk '{print $4}'|xargs kill

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.