Come posso chiudere un terminale senza uccidere i suoi figli (senza prima eseguire `screen`)?


35

a volte eseguo un'app nel terminale GNOME, ma poi improvvisamente devo riavviare GNOME o qualcosa del genere. Immagino che anche la risposta alla domanda sia utile, quindi voglio disconnettermi da SSH dove sta succedendo qualcosa.

L'albero terminale di Gnome è simile al seguente:

gnome-terminal
    bash
        some-boring-process

Posso 'staccare' bashda gnome-terminal(o staccare some-boring-processda bash e reindirizzare la sua uscita da qualche parte)? Se uccido gnome-terminal, bashsaranno uccisi per tutti i suoi sottoprocessi


Risposte:


48

Se some-boring-processè in esecuzione nella sessione bash corrente:

  1. fermalo con ctrl-zper darti il ​​prompt bash
  2. mettilo in background con bg
  3. annotare il numero del lavoro o utilizzare il jobscomando
  4. staccare il processo da questa sessione bash con disown -h %1(sostituire lì il numero effettivo del lavoro).

Ciò non fa nulla per reindirizzare l'output: devi pensarci quando avvii il tuo noioso processo. [Modifica] Sembra esserci un modo per reindirizzarlo https://gist.github.com/782263

Ma seriamente, guarda nello schermo. Ho delle shell su un server remoto che funzionano da mesi.


Grazie. Ho selezionato la tua risposta perché era l'unica a rispondere alla domanda (si trattava già di un processo in corso). Lo sto già usando a screenvolte, anche se ha i suoi problemi e non voglio usarlo per ogni sessione bash della mia vita
Valya,

Non lo usi per ogni sessione di bash, ma per ogni macchina remota in cui trascorri molto tempo.
Glenn Jackman,

Mi sono preso la libertà di aggiungere informazioni sul reindirizzamento dell'output, si prega di rivederlo!
Valya,

[root @ server ~] # bg -bash: bg: corrente: nessun lavoro simile
Muhammad Dyas Yaskur

Perché l'ho preso bash: bg: current: no such job?
Muhammad Dyas Yaskur il

10

Questo è esattamente ciò per cui sono stati creati screen e tmux . Esegui la shell all'interno della sessione screen / tmux e puoi disconnetterti / riconnetterti a piacimento. Puoi anche avere più sessioni di shell in esecuzione all'interno di un terminale gnome.


Grazie, ma, come ho commentato alla risposta accettata: 1. la domanda riguardava il processo già in esecuzione. 2. screenha i suoi problemi e non mi va di usarlo per tutte le sessioni bash della mia vita
valya

6

screen, tmuxo dtach(possibilmente con dvtm) sono tutti ottimi per questo, ma se è qualcosa in cui non hai pensato di usarne uno, potresti essere in grado di sfruttare nohup.


Grazie, ma, come ho commentato alla risposta accettata: 1. la domanda riguardava il processo già in esecuzione. 2. screenha i suoi problemi e non mi va di usarlo per tutte le sessioni bash della mia vita
valya

@valya Sono contento che hai trovato una soluzione. Solo per essere chiari, tuttavia, nohupfunziona su un processo in esecuzione utilizzando l' -popzione (se disponibile).
Hank Gay

@Hank Gay: non riesco a vedere -pun'opzione nohupnelle pagine man; su quale sistema sei?
Mikel

@Mikel Prima ho imparato a smettere di preoccuparmi e ad amare tmux , ho usato l' -popzione su una scatola di Solaris. Ho anche vaghi ricordi di averlo fatto su un box CentOS ibrido (forse zshha un builtin che lo supporta?), Ma non riesco a trovare alcun documento su questo.
Hank Gay

@Hank Gay: Nemmeno bashzshsul mio sistema Ubuntu Linux né sul mio sistema nohup.
Mikel

4

Se vuoi continuare a interagire con il processo figlio invece di limitarti a metterlo in background e farlo andare avanti, in realtà c'è un programma chiamato retty che è una prova di concetto per "rubare" un processo dalla sua tty corrente e ricollegarlo al quello attuale.

Tuttavia, fa alcune cose orribili, incluso attaccare un po 'di codice assembly allo stack dell'applicazione ricollegata. E quel codice non è stato aggiornato per x86_64.

C'è un altro programma che adotta un approccio forse migliore, congelando il processo nello spazio utente in un file, dal quale può essere successivamente ripristinato (possibilmente su un altro tty). Questo è criope , e anche quel progetto sembra essersi fermato nel fase di prova di concetto, e non funziona con Linux moderno come il codice sta. Ah bene.

Ho pensato che questo dovrebbe essere qui per completezza. Se non ti dispiace ricorrere al voodoo orribile, questo è nel regno della possibilità - almeno, possibilità teorica.


1
che mi ricorda gist.github.com/782263 ... oh, anche quel succo sembra rispondere alla mia domanda
Valya

2

Se accendo qualcosa che voglio finire, indipendentemente dal riavvio del sistema, lo utilizzo nohuped eseguo in background. A differenza dello schermo e simili non è possibile ricollegarsi ai processi. Tuttavia, escludendo il reindirizzamento altrove è possibile trovare qualsiasi output nohup.out.

Lo uso screenquando voglio essere in grado di cambiare terminale per un processo. Come iniziare un processo da casa / lavoro e passare all'altro. Come qualsiasi altra uscita di sessione terminale, scorrerà eventualmente dalla parte superiore del buffer.

EDIT: se il processo è già stato avviato, è possibile eseguire disownil processo per impedire che il HUPsegnale venga inviato alla chiusura del processo.


Grazie, ma, come ho commentato alla risposta accettata: 1. la domanda riguardava il processo già in esecuzione. 2. screenha i suoi problemi e non mi va di usarlo per tutte le sessioni bash della mia vita
valya

@valya Ho visto riferimenti a disconnettere un processo in esecuzione dal gruppo di programmi. Non conosco alcuno strumento per farlo. Lo strumento dovrebbe probabilmente reindirizzare anche i canali IO standard. Penso che potrei averlo fatto funzionare una volta, ma ho deciso che nohup era più semplice.
BillThor

1

È possibile fare in modo che un processo (PID) non riceva un segnale HUP al termine della sessione del terminale. Utilizzare il comando seguente:

nohup -p PID

nohup: invalid option -- 'p'. Quale versione di nohupstai utilizzando su quale tipo di sistema?
Anthon,

Uso principalmente Solaris e AIX. Per Linux, dovresti controllare il comando disown.
tony,

Sì, non c'è alcuna -popzione su Linux, quindi questa risposta è specifica per Solaris e AIX. Buono a sapersi però
Sergiy Kolodyazhnyy

1

Questo script stacca il processo figlio dal genitore e lo assegna al processo init :

toDetach=$1

./$toDetach & # Runs the process - script on background

disown -h %$(jobs -l | grep $(ps -A | grep $toDetach | cut --delimiter=' ' -f1) | cut --delimiter=' ' -f1 | tr -d '[]+') # and then disowns it from parents process
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.