Uccidi il processo generato da ssh quando muore ssh


23

Questa è una domanda che è stata affrontata più volte, non solo qui, ma anche in altri siti della rete di scambio di stack (ad esempio come fare in modo che ssh uccida il processo remoto quando interrompo ssh stesso? ). Tuttavia, non posso far funzionare nessuna delle soluzioni per me.

Sto eseguendo un comando tramite ssh. Ogni volta che esco da ssh, voglio che anche il comando muoia. Questo comando è un demone chiamato ktserver che gira indefinitamente finché non premi Ctrl-C.

Lo eseguo come segue: ssh -t compute-0-1 ktservere, in effetti, quando premo Ctrl-C, il processo termina con grazia e termina la sessione ssh.

Tuttavia, se invece di premere Ctrl-C, uccido il processo ssh usando il killcomando (ad esempio, inviando SIGINT o SIGHUP), il ktserverprocesso rimane attivo .

Come posso rendere il ktservermorire sempre indipendente su come sshviene ucciso?

EDIT : Se, invece di ktservereseguire qualcosa di completamente diverso, come gedit, tutto funziona come un incantesimo (cioè gedit muore quando la connessione si interrompe). Pertanto, potrebbe esserci qualcosa di sbagliato nel processo stesso. Ad esempio, ho pensato che potrebbe ignorare SIGHUP o SIGINT. Tuttavia, quando eseguo kill -1 ktservero kill -2 ktserver, il processo termina come previsto.

EDIT2 : Come sottolinea Mark Plotnick, il problema è legato al fatto che non vi sono comunicazioni in circolazione sul canale ssh. Ho confermato eseguendo ssh -t <host> reade uccidendo il processo ssh in seguito. readera ancora vivo e vegeto.


Ci hai provato kill -9 ktserver?

@HermanTorjussen Certo, che funziona. Il problema è che questo comando viene eseguito da un altro processo e potrei non avere il controllo su tutte le molte possibilità che potrebbero causare la morte del mio processo, e quindi la sessione ssh con esso. Quindi ho bisogno di un modo affidabile per essere sicuro che ogni volta che il mio processo - e quindi lo fa - muore, ktserver morirà con loro.
GermanK,

La mia esperienza con Linux è che se il comando remoto non esegue alcun I / O alla connessione dead tcp, continuerà a funzionare. Ho ssh example.com dd ...completato i lavori anche poche ore dopo l' sshinterruzione della connessione a causa di problemi di rete. Se puoi modificare ktserverl'opzione per produrre qualcosa di tanto in tanto, questa potrebbe essere una soluzione alternativa.
Mark Plotnick,

@MarkPlotnick In effetti, ho provato a correre readsul computer remoto e dopo aver ucciso la connessione SSH readnon sono morto. Sfortunatamente, non riesco a cambiare ktserver per produrre nulla. Allora non c'è soluzione?
GermanK,

2
Presumo che quando muore ssh anche il tuo guscio muore. Puoi configurare la tua shell per inviare un segnale -1 (SIGHUP) quando termina. ( shopt -s huponexit). Puoi provare se questo funziona per te?
Hennes,

Risposte:


13

Di solito quando la connessione ssh muore, anche la shell muore. Puoi configurare la tua shell per inviare un segnale -1 (SIGHUP) quando termina a tutti i suoi figli.

Per bash puoi configurare questa opzione tramite il comando incorporato shopt . ( shopt -s huponexit).

Per zsh che vuoi .setoptHUP


Ho pensato che questa fosse la risposta al mio attuale problema, ma non sembra funzionare. Sto correndo: ssh $ host "scp LargeFile.dat $ OtherHost: / tmp" & pid = $! e poi cercando di fermare quel trasferimento con: shopt -s huponexit; kill $ pid, ma lo scp non si ferma quando uccido lo ssh che ho iniziato. qualche idea?
David Doria,

Puoi testare con le opzioni di shell impostate prima di avviare il comando scp? O avviando una shell, impostando shopt e avviando scp?
Hennes,

2
Questo funziona per me, ma prima dovevo assicurarmi che stavo usando ssh -t -t(notate -tdue volte!) Che forza l'allocazione di tty, piuttosto che solo pty.
Nicolas Wu,

13

Ho scoperto che semplicemente usando -t -tcome argomento per sshfarlo funzionare. Non ho dovuto impostare huponexitla shell di origine o remota.

Ho provato questo come segue:

Non funziona:

ssh user@remote sleep 100
^C

Questo ha ucciso la sessione ssh, ma vedo che il processo di sospensione è ancora in esecuzione sull'host remoto (lo ps -ef | grep sleepmostra).

Funziona:

ssh -t -t user@remote sleep 100
^C

Questo uccide la sessione ssh e anche il processo di sonno remoto è stato ucciso. Ho anche verificato che il segnale che viene inviato al processo remoto è SIGINTse usi Control- C. Ho anche verificato che SIGKILL (-9) applicato al sshprocesso ucciderà anche il processo remoto.

MODIFICA 1:

Questo era vero per sleep... per processi remoti più ostinati, ho scoperto che sshgestisce ^ C in modo diverso da SIGINT. Ctrl- ha Cfunzionato, ma kill -INT $piddidn'.t

Ecco cosa ho finalmente pensato che ha funzionato per la mia effettiva applicazione (rubando dalle altre risposte).

ssh -t -t -i id_rsa user@mic0 "/bin/sh -O huponexit -c 'sleep 100'"

Nota l'uso annidato di virgolette doppie e virgolette singole. Nota che il tuo processo remoto DEVE rispondere a SIGHUP uscendo davvero!


Questo ha funzionato meglio per me, ma FYI, ha anche causato il sanguinamento dei caratteri di controllo del terminale, il che può causare output divertenti. Quindi, la soluzione semplice nel mio caso era quella di racchiudere i comandi chiamati e reindirizzare il loro output cat. Ad esempio,ssh -ttq user@host '{ cmd; cmd; } | cat'
Droj il

Ctrl-Cnon è sempre equivalente a kill -INT $pid, vedere la mia risposta su unix.stackexchange.com/questions/377191/... e un altro sul stackoverflow.com/questions/8398845/... per i dettagli scabrosi ;-)
thecarpy

@thecarpy - la tua prima risposta dice che Ctrl-C è simile a SIGINT , e l'altra risposta dice che ^Cinvia SIGINT . Quindi qual è la differenza esatta se non sono equivalenti?
Mark Lakata,

1

Se ssh non propaga segnali riceve ciò che ti aspetteresti da esso?

UPD. (speciale per JosephR): è ovviamente un errore in questione in sé che deriva da incomprensioni: "Il processo di uccisione generato da ssh quando ssh muore". SSH di solito non genera processi (a volte lo fa, ma questa è un'altra storia), invece SSHD, quando guardiamo dall'altra parte della connessione. SSH si basa semplicemente sull'astrazione pseudo-terminale remota del server. Ecco perché l'unica cosa che può essere di aiuto è la capacità del terminale di emettere segnali ai suoi processi collegati. Questo è in qualche modo molto semplice per ogni sistema simile a UNIX.


1
Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti a un autore, lascia un commento sotto il suo post.
Anthon,

@Anthon, è una spiegazione. Ma nessuno afferma che questa dovrebbe essere l'unica risposta corretta. Grazie per il tuo commento qui sotto.
poige,

1
@poige Forse arricchire la spiegazione in modo che possa essere utile all'OP e ad altri.
Joseph R.

@JosephR., Ok, solo per te.
poige,

1
Se dico "Uccidi il processo generato da sshd quando la connessione ssh viene persa" ti suonerebbe meglio? Non penso che la riformulazione risolva il mio problema in alcun modo.
GermanK,

0

La soluzione pubblicata qui non ha funzionato per me, ma poiché questa domanda è emersa per prima quando stavo cercando una soluzione a un problema simile e anche -t -tqui è stato menzionato il trucco, posterò una soluzione che ha funzionato per me per gli altri.

ssh -t -t -o ControlMaster=auto -o ControlPath='~/test.ssh' your_remote_ip_goes_here "your_long_running_command" &
sleep 100
ssh -o ControlPath='~/test.ssh' -O exit your_remote_ip_goes_here

Il mio comando long running non funzionava più quando la connessione era terminata in questo modo.

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.