Perbedaan antara nohup, disown, & &

578

Apa perbedaannya

$ nohup foo

dan

$ foo &

dan

$ foo & 
$ disown
lesmana
sumber
50
Tunggu, Anda dapat menolak tanpa menentukan PID? Bagus!
ripper234
34
Ada juga foo &!yang harus sama dengan menolaknya sejak awal.
user4514
26
Bash tidak mendukung & !.
Jonas Kongslund
20
foo & disownuntuk disangkal segera.
ctrl-alt-delor
9
Saya ingin melihat penyebutan setsid, dan bagaimana kaitannya dengan disowndannohup
YoungFrog

Jawaban:

557

Pertama mari kita lihat apa yang terjadi jika suatu program dimulai dari shell interaktif (terhubung ke terminal) tanpa &(dan tanpa pengalihan). Jadi mari kita asumsikan Anda baru saja mengetik foo:

  • Proses yang berjalan foodibuat.
  • Proses mewarisi stdin, stdout, dan stderr dari shell. Karena itu juga terhubung ke terminal yang sama.
  • Jika shell menerima a SIGHUP, shell juga mengirimkan SIGHUPke proses (yang biasanya menyebabkan proses berakhir).
  • Kalau tidak, shell menunggu (diblokir) sampai proses berakhir.

Sekarang, mari kita lihat apa yang terjadi jika Anda meletakkan proses di latar belakang, yaitu, ketik foo &:

  • Proses yang berjalan foodibuat.
  • Proses ini mewarisi stdout / stderr dari shell (sehingga masih menulis ke terminal).
  • Proses pada prinsipnya juga mewarisi stdin, tetapi begitu ia mencoba membaca dari stdin, ia dihentikan.
  • Ini dimasukkan ke dalam daftar pekerjaan latar belakang yang dikelola shell, yang artinya terutama:
    • Itu terdaftar dengan jobsdan dapat diakses menggunakan %n(di mana nnomor pekerjaan).
    • Ini dapat diubah menjadi pekerjaan latar depan menggunakan fg, dalam hal ini terus berlanjut seolah-olah Anda tidak akan menggunakannya &(dan jika dihentikan karena mencoba membaca dari input standar, sekarang dapat melanjutkan membaca dari terminal).
    • Jika shell menerima SIGHUP, itu juga mengirimkan SIGHUPke proses. Tergantung pada shell dan mungkin pada opsi yang ditetapkan untuk shell, ketika mengakhiri shell itu juga akan mengirim SIGHUPke proses.

Sekarang disownhapus pekerjaan dari daftar pekerjaan shell, jadi semua subpoint di atas tidak berlaku lagi (termasuk proses yang dikirim SIGHUPoleh shell). Namun perlu dicatat bahwa itu masih terhubung ke terminal, jadi jika terminal dihancurkan (yang dapat terjadi jika itu pty, seperti yang dibuat oleh xtermatau ssh, dan program pengendali dihentikan, dengan menutup xterm atau mengakhiri koneksi SSH ) , program akan gagal segera setelah mencoba membaca dari input standar atau menulis ke output standar.

Apa yang nohupdilakukan, di sisi lain, adalah untuk secara efektif memisahkan proses dari terminal:

  • Ini menutup input standar (program tidak akan dapat membaca input apa pun, bahkan jika dijalankan di latar depan. Itu tidak dihentikan, tetapi akan menerima kode kesalahan atau EOF).
  • Ini mengarahkan output standar dan kesalahan standar ke file nohup.out, sehingga program tidak akan gagal untuk menulis ke output standar jika terminal gagal, sehingga apa pun proses penulisan tidak hilang.
  • Ini mencegah proses dari menerima SIGHUP(dengan demikian nama).

Perhatikan bahwa nohuptidak tidak menghapus proses dari kontrol pekerjaan shell dan juga tidak meletakkannya di latar belakang (tapi karena latar depan nohuppekerjaan lebih atau kurang berguna, Anda akan umumnya memasukkannya ke dalam latar belakang menggunakan &). Misalnya, tidak seperti dengan disown, shell masih akan memberi tahu Anda ketika pekerjaan nohup telah selesai (kecuali jika shell sudah diakhiri sebelumnya, tentu saja).

Jadi untuk meringkas:

  • & menempatkan pekerjaan di latar belakang, yaitu, membuatnya memblokir upaya membaca input, dan membuat shell tidak menunggu penyelesaiannya.
  • disownmenghapus proses dari kontrol pekerjaan shell, tetapi masih membiarkannya terhubung ke terminal. Salah satu hasilnya adalah shell tidak mau mengirimkannya SIGHUP. Jelas, itu hanya dapat diterapkan pada pekerjaan latar belakang, karena Anda tidak dapat memasukkannya saat pekerjaan latar depan sedang berjalan.
  • nohupmemutus proses dari terminal, mengalihkan hasilnya ke nohup.outdan melindunginya dari SIGHUP. Salah satu efek (penamaan) adalah bahwa proses tidak akan menerima pengiriman apa pun SIGHUP. Ini sepenuhnya independen dari kontrol pekerjaan dan pada prinsipnya dapat digunakan juga untuk pekerjaan latar depan (meskipun itu tidak terlalu berguna).
celtschk
sumber
8
+1 Terima kasih. Apa yang terjadi ketika menggunakan disown, nohup dan & bersama?
Tim
15
Jika Anda menggunakan ketiganya bersama-sama, proses berjalan di latar belakang, dihapus dari kontrol pekerjaan shell dan secara efektif terputus dari terminal.
celtschk
1
apa perbedaan antara disown %1dan disown -h %1? Yang kedua akan tetap sebagai pekerjaan biasa (tetapi mengabaikan sinyal HUP) sampai terminal keluar?
schemacs
4
Mungkin layak termasuk (foo&)subkulit
jiggunjer
169

Menggunakan &menyebabkan program berjalan di latar belakang, sehingga Anda akan mendapatkan prompt shell baru alih-alih memblokir sampai program berakhir. nohupdan disownsebagian besar tidak terkait; mereka menekan sinyal SIGHUP (hangup) sehingga program tidak mati secara otomatis ketika terminal pengendali ditutup. nohupmelakukan ini ketika pekerjaan pertama dimulai. Jika Anda tidak melakukan nohuppekerjaan saat dimulai, Anda dapat menggunakan disownuntuk memodifikasi pekerjaan yang sedang berjalan; tanpa argumen itu memodifikasi pekerjaan saat ini, yang merupakan hanya latar belakang

Michael Mrozek
sumber
10
Perbedaan kecil antara nohup dan disown: perintah disown akan menghapusnya dari daftar pekerjaan Anda; tidak akan.
Shawn J. Goff
191
nohupdan disownkeduanya dapat dikatakan menekan SIGHUP, tetapi dengan cara yang berbeda. nohupmembuat program mengabaikan sinyal awalnya (program dapat mengubah ini). nohupjuga mencoba mengatur agar program tidak memiliki terminal pengendali, sehingga tidak akan dikirim SIGHUPoleh kernel ketika terminal ditutup. disownmurni internal ke shell; itu menyebabkan shell tidak mengirim SIGHUPketika itu berakhir.
Gilles
27
@Gilles, komentar Anda layak dijawab sendiri.
lesmana
5
Hanya klarifikasi pada komentar @ ShawnJ.Goff yang berkaitan dengan disownmenghapus pekerjaan dari daftar pekerjaan. Jika Anda tidak menentukan opsi, itu menghapusnya dari daftar pekerjaan. Namun , jika Anda menentukan -hopsi, setiap jobspec tidak dihapus dari tabel. Sebagai gantinya, ia membuatnya agar SIGHUPtidak dikirim ke pekerjaan jika shell menerima a SIGHUP.
tacotuesday
4
Hanya untuk memperjelas, menggunakan &tidak memberi Anda terminal, itu terlepas stdindari proses dan menyebabkannya berjalan di latar belakang, tetapi keduanya stdoutdan stderrmasih melekat pada tty saat ini. Ini berarti Anda mungkin mendapatkan teks dari berbagai program yang digabungkan, yang bisa sangat menjengkelkan jika Anda melakukan gimp &dan mendapatkan banyak kesalahan GTK + saat mencoba menggunakan tty itu untuk sesuatu yang lain.
Frank
8

Inilah pengalaman saya mencoba menjalankan soffice di latar belakang, mengikuti perintah yang tidak berakhir (mis tail.). Untuk contoh ini saya akan gunakan sleep 100.

&

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Saya melihat soffice log / dengan menekan Ctrl- Csoffice stops

tidak ... &

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Saya tidak melihat log kantor / dengan menekan Ctrl- Cberhenti kantor

& ditolak

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

Saya melihat soffice log / dengan menekan Ctrl- Csoffice stops

setid .. &

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Saya melihat log soffice / dengan menekan Ctrl- Csoffice TIDAK BERHENTI

Untuk menghemat ruang::
nohup setsid ..tidak menampilkan log / soffice JANGAN BERHENTI Ctrl-C
nohup dengan & disownpada akhirnya: tidak menunjukkan log / soffice berhenti aktif Ctrl-C

Marinos An
sumber
2
Sementara saya menghargai upaya menyebutkan setid dan menunjukkan apa yang terjadi dalam situasi khusus itu, saya ingin melihat jawaban yang lebih menyeluruh. Khususnya perbedaan dan persamaan dari setiap solusi, baik yang terlihat (apa yang terjadi ketika menutup shell atau terminal, ke mana output pergi, ...) dan tidak terlihat (bagaimana hal-hal dilakukan di bawah tenda dan implikasinya). Jawaban yang diterima adalah dasar yang bagus untuk itu.
YoungFrog
1
@YoungFrog Saya akan menyetujui ini!
Marinos An
Bagi saya, dengan nohup ⟨command⟩ & disownproses yang dibuat tidak berhenti Ctrl+C.
k.stm
@ k.stm Sudahkah Anda mencoba soffice? sofficePerintah sepertinya memiliki sesuatu yang berbeda. Jadi saya mempertimbangkan untuk menambahkannya di sini sebagai pengecualian aturan. misalnya ketika menggunakan nohup .. &:, menekan secara Ctrl-cnormal tidak menyebabkan perintah berhenti, tetapi dengan sofficeitu tidak. Saya menunggu sampai seseorang menginjak ini dan menjelaskan mengapa ini terjadi dengan soffice :)
Marinos An
@MarinosAn Ya, saya lakukan. Aku berlari nohup soffice &dan menekan Ctrl+C. Tidak ada yang terjadi, seperti yang diharapkan.
k.stm