Come faccio a fork un processo che non muore quando esce la shell?


31

Se eseguo emacs dalla shell:

$ emacs foo &

e poi uccidi quel guscio, emacs muore.

Come posso eseguire un comando in modo che non muoia quando muore la shell?

Ho trovato riferimenti a nohup, ma questo non sembra aiutare:

$ nohup emacs foo &

uccide ancora gli emacs quando muore il guscio.

Risposte:


13

Non menzionate se questo è in esecuzione come app X o console.

Se è come un'app console, ovviamente deve chiudere. Ti sei sbarazzato del suo input / output, più tecnicamente lo (pseudo) tty era acceso. È molto improbabile che questo sia ciò che intendevi, quindi supponiamo che tu stia parlando di un'app X.

nohupdovrebbe funzionare, non so perché non lo sia. Quando la shell si chiude, invia SIGHUPa tutti i processi nel suo gruppo di processi. nohup dice al comando di ignorare SIGHUP.

Puoi anche provare setsid, che disconnette il processo dal gruppo di processi

alias emacs='setsid emacs'

O aggiungi disowndopo&


Ah, grandi opere setid. Mi dispiace non essere chiaro. Sì, mi riferisco alle app X che non vengono effettivamente eseguite nella shell. Fondamentalmente, voglio avviare emacs (o qualsiasi altro processo) dalla shell, ma non lo voglio in alcun modo legato alla shell. Lo sto iniziando lì per comodità.
Sligocki,

41

Il metodo più affidabile sembra essere:

(setsid emacs &)

Questo utilizza ( &)per passare allo sfondo e setsidper staccare dal tty di controllo.

Puoi metterlo in una funzione shell:

fork() { (setsid "$@" &); }

fork emacs

Le possibilità sono:

  • Il disowncomando incorporato:

    emacs &
    disown $!
    

    &funge da separatore di comandi e disownpasserà automaticamente al lavoro più recente, quindi può essere abbreviato in:

    emacs & disown
    
  • Doppio fork():

    (emacs &)
    

    I comandi tra parentesi ( )vengono eseguiti in un processo shell separato.

  • setsid, come suggerito da Rich, potrebbe essere la scelta migliore, perché annulla il TTY di controllo del processo creando una nuova sessione :

    setsid emacs
    

    Tuttavia, è anche un po 'imprevedibile: farà lo fork()sfondo solo se è il leader di un gruppo di processi (cosa che non accadrà se setsidusato in uno shscript, per esempio; in tali occasioni diventerà semplicemente resistente a Ctrl- C.)


Grande! questi funzionano tutti per me. Bello avere altri strumenti nel mio arsenale.
Sligocki,

Hm ... avrebbe (exec emacs)funzionato?
Hello71,

@Ciao: non sarebbe diverso da solo (emacs). Se alla subshell viene dato un singolo comando, execè implicito, almeno in caso di bash. Lo stesso vale per bash -c 'foo'contro bash -c 'exec foo'. (Tuttavia, si noti che emacs stesso potrebbe staccarsi dal terminale; gvim, ad esempio, lo fa. È meglio provare con un programma con comportamento noto.)
Grawity

Ottimo per conoscere la tecnica della doppia forcella; Grazie!
Dave Abrahams,

Ho trovato questo mentre cercavo di risolvere un problema per conto mio. (Setsid emacs &) ha funzionato per me. Grazie per una risposta ben scritta.
Paulb,

5

Controlla le impostazioni della shell. Puoi anche provare lo schermo invece di nohup.


Lo schermo ti consente di riavviare il processo in un secondo momento screen -rse si utilizza Ctrl-A Ctrl-Dper disconnetterlo prima di disconnettersi.
Broam,

Questo è un ottimo punto. Avevo bisogno del contrario, ovvero biforcare una subshell e procedere con altre attività senza attendere il suo completamento, ma screen -d -m sh -c "{do stuff } exit"ha molto più senso.
Nemo,
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.