Bagaimana saya memotong proses yang tidak mati saat shell keluar?

31

Jika saya menjalankan emacs dari shell:

$ emacs foo &

dan kemudian bunuh cangkang itu, emacs mati.

Bagaimana saya bisa menjalankan perintah sehingga tidak akan mati ketika shell mati?

Saya menemukan referensi ke nohup, tetapi itu sepertinya tidak membantu:

$ nohup emacs foo &

masih membunuh emacs ketika shell mati.

sligocki
sumber

Jawaban:

13

Anda tidak menyebutkan apakah ini berjalan sebagai aplikasi X atau aplikasi konsol.

Jika itu sebagai aplikasi konsol, tentu saja harus ditutup. Anda menyingkirkan input / output, lebih teknis (pseudo) tty itu aktif. Sangat tidak mungkin ini yang Anda maksud, jadi mari kita asumsikan Anda sedang berbicara tentang aplikasi X.

nohupharus bekerja, tidak yakin mengapa tidak. Ketika shell ditutup, ia mengirim SIGHUPke semua proses dalam grup prosesnya. nohup memberi tahu perintah untuk mengabaikan SIGHUP.

Anda juga dapat mencoba setsid, yang memutuskan proses dari grup proses

alias emacs='setsid emacs'

Atau tambahkan disownsetelah&

Homolka yang kaya
sumber
Ah, karya bagus setid. Maaf karena tidak jelas. Ya saya merujuk ke aplikasi X yang tidak benar-benar berjalan di shell. Pada dasarnya, saya ingin memulai emacs (atau proses lainnya) dari shell, tapi saya tidak ingin itu terikat dengan shell. Saya baru mulai di sana untuk kenyamanan.
sligocki
41

Metode yang paling dapat diandalkan tampaknya adalah:

(setsid emacs &)

Ini digunakan ( &)untuk bercabang ke latar belakang, dan setsiduntuk melepaskan diri dari tty mengendalikan.

Anda dapat menempatkan ini dalam fungsi shell:

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

fork emacs

Kemungkinannya adalah:

  • The disownperintah builtin:

    emacs &
    disown $!
    

    &bertindak sebagai pemisah perintah, dan disownakan default ke pekerjaan terbaru, sehingga ini dapat disingkat menjadi:

    emacs & disown
    
  • Ganda- fork():

    (emacs &)
    

    Perintah di dalam tanda kurung ( )dijalankan dalam proses shell terpisah.

  • setsid, seperti yang disarankan oleh Rich, mungkin merupakan pilihan terbaik, karena ia tidak mengatur TTY pengontrol proses dengan membuat sesi baru :

    setsid emacs
    

    Namun, ini juga sedikit tidak dapat diprediksi - ini hanya akan fork()menjadi latar belakang jika itu adalah pemimpin kelompok proses (yang tidak akan terjadi jika setsiddigunakan dalam shskrip, misalnya; dalam kesempatan seperti itu hanya akan menjadi tahan terhadap Ctrl- C.)

grawity
sumber
Besar! ini semua bekerja untuk saya. Senang memiliki beberapa alat di gudang senjata saya.
sligocki
Hm ... akan (exec emacs)berhasil?
Hello71
@ Halo: Tidak akan berbeda dengan adil (emacs). Jika subshell diberikan satu perintah, execitu tersirat, setidaknya dalam kasus bash. Hal yang sama berlaku untuk bash -c 'foo'versus bash -c 'exec foo'. (Namun, perhatikan bahwa emacs sendiri mungkin terlepas dari terminal; gvim, misalnya, melakukan ini. Lebih baik untuk menguji dengan program dengan perilaku yang diketahui.)
grawity
Bagus untuk belajar teknik garpu ganda; Terima kasih!
Dave Abrahams
Menemukan ini saat trolling untuk memperbaiki masalah saya sendiri. (Setsac emacs &) bekerja untuk saya. Terima kasih atas jawaban yang ditulis dengan baik.
Paulb
5

Periksa pengaturan shell Anda. Anda juga dapat mencoba layar alih-alih nohup.

Josh K.
sumber
Layar memungkinkan Anda untuk kembali ke proses nanti dengan screen -rjika Anda gunakan Ctrl-A Ctrl-Duntuk memutuskannya sebelum logout.
Broam
Ini adalah poin yang sangat bagus. Saya membutuhkan yang sebaliknya, yaitu mencari subkulit dan melanjutkan dengan tugas-tugas lain tanpa menunggu penyelesaiannya, tetapi screen -d -m sh -c "{do stuff } exit"jauh lebih masuk akal.
Nemo