Pertanyaan Bagaimana saya melepaskan proses dari Terminal, sepenuhnya?


Saya menggunakan Tilda (drop-down terminal) di Ubuntu sebagai "pusat perintah" saya - cukup banyak cara orang lain menggunakan GNOME Do, Quicksilver atau Launchy.

Namun, saya berjuang dengan cara benar-benar melepaskan proses (misalnya Firefox) dari terminal yang diluncurkan dari - yaitu mencegah proses anak (non-)

  • diakhiri ketika menutup terminal asal
  • "Mencemari" terminal asal melalui STDOUT / STDERR

Misalnya, untuk memulai Vim di jendela terminal "tepat", saya telah mencoba skrip sederhana seperti berikut:

exec gnome-terminal -e "vim $@" &> /dev/null &

Namun, itu masih menyebabkan polusi (juga, melewatkan nama file tampaknya tidak berfungsi).


274
2018-03-23 11:59


asal


Itu juga pertanyaan yang bagus. Saya pikir itu adil untuk mempertimbangkan Bash suatu bahasa pemrograman - meskipun memang lingkup pertanyaan ini mungkin lebih pada sisi sysadmin ...
Ini adalah duplikat dari pertanyaan ini stackoverflow.com/questions/285015/… - Dana the Sane
dup dari:superuser.com/questions/177218/… - behrooz
Kasus penggunaan Anda tidak menggambarkan detasemen lengkap, per se. - jiggunjer


Jawaban:


Pertama-tama; setelah Anda memulai suatu proses, Anda dapat melaluinya dengan terlebih dahulu menghentikannya (klik Ctrl-Z) dan kemudian mengetik bg untuk membiarkannya melanjutkan di latar belakang. Ini sekarang "pekerjaan", dan itu stdout/stderr/stdin masih terhubung ke terminal Anda.

Anda dapat memulai proses sebagai latar belakang segera dengan menambahkan "&" ke bagian akhir:

firefox &

Untuk menjalankannya di latar belakang yang dibungkam, gunakan ini:

firefox </dev/null &>/dev/null &

Beberapa info tambahan:

nohup adalah program yang dapat Anda gunakan untuk menjalankan aplikasi Anda sehingga stdout / stderrnya dapat dikirim ke sebuah file dan menutup script induk tidak akan memperketat anak. Namun, Anda harus memiliki kejelian untuk menggunakannya sebelum Anda memulai aplikasi. Karena jalannya nohup bekerja, Anda tidak bisa begitu saja menerapkannya ke proses yang sedang berjalan.

disown adalah bash built-in yang menghilangkan pekerjaan shell dari daftar pekerjaan shell. Apa artinya ini pada dasarnya adalah bahwa Anda tidak dapat menggunakan fg, bg di atasnya lagi, tetapi yang lebih penting, ketika Anda menutup shell Anda tidak akan menggantung atau mengirim SIGHUP kepada anak itu lagi. Tidak seperti nohup, disown digunakan setelah proses telah diluncurkan dan dilatarbelakangi.

Apa kamu tidak bisa lakukan, adalah mengubah stdout / stderr / stdin dari suatu proses setelah meluncurkannya. Setidaknya bukan dari cangkangnya. Jika Anda memulai proses Anda dan mengatakan bahwa stdout-nya adalah terminal Anda (yang Anda lakukan secara default), maka proses itu dikonfigurasikan untuk dikeluarkan ke terminal Anda. Shell Anda tidak memiliki bisnis dengan pengaturan FD proses, itu murni sesuatu yang dikelola oleh proses itu sendiri. Proses itu sendiri dapat memutuskan apakah akan menutup stdout / stderr / stdin atau tidak, tetapi Anda tidak dapat menggunakan shell Anda untuk memaksanya melakukannya.

Untuk mengelola output proses latar belakang, Anda memiliki banyak pilihan dari skrip, "nohup" mungkin menjadi yang pertama muncul di pikiran. Tetapi untuk proses interaktif yang Anda mulai tetapi lupa untuk diam (firefox < /dev/null &>/dev/null &) Anda tidak bisa berbuat banyak, sungguh.

Saya sarankan Anda mendapatkan GNU screen. Dengan layar, Anda bisa menutup shell yang sedang berjalan ketika output proses menjadi repot dan membuka yang baru (^Ac).


Oh, dan ngomong-ngomong, jangan gunakan "$@"di mana kamu menggunakannya.

$@cara, $1, $2, $3 ..., yang akan mengubah perintahmu menjadi:

gnome-terminal -e "vim $1" "$2" "$3" ...

Itu mungkin bukan yang Anda inginkan karena -s hanya membutuhkan waktu satu argumen. Menggunakan $1 untuk menunjukkan bahwa skrip Anda hanya dapat menangani satu argumen.

Sangat sulit untuk mendapatkan beberapa argumen bekerja dengan benar dalam skenario yang Anda berikan (dengan gnome-terminal -e) karena -e hanya membutuhkan satu argumen, yang merupakan string perintah shell. Anda harus mengkodekan argumen Anda menjadi satu. Cara terbaik dan paling kuat, tapi agak kasar, seperti ini:

gnome-terminal -e "vim $(printf "%q " "$@")"

308
2018-03-23 13:18



Terima kasih banyak untuk ini! Sayangnya saya hanya bisa menerima satu jawaban. Saya berakhir dengan "nohup $ @ &> / dev / null &" dan "alias wvim = 'launch.sh gnome-terminal -x vim'"
Jawaban yang sangat mendetail dan informatif. +1 - Teekin
@ Hi-Angel ketika Anda menutup bash shell interaktif, bash HUPs semua pekerjaan aktif. Ketika Anda ^ Z dan bg proses itu masih pekerjaan, baik itu satu latar belakang. Untuk menghapusnya sebagai pekerjaan, gunakan disown, maka proses akan terus hidup setelah Anda menutup shell karena bash tidak akan HUP lagi. - lhunath
Tidak akan menggunakan $* dari pada $@ memperbaiki masalah string yang terpisah sudah? - sjas
Apa yang tidak dapat Anda lakukan, adalah mengubah stdout / stderr / stdin dari suatu proses setelah meluncurkannya. - tidak sepenuhnya benar. Menggunakan reptyr untuk ini. - Stefan Seidel


nohup cmd &

nohup lepaskan proses sepenuhnya (mendemonstrasikannya)


190
2018-03-23 12:17



Meskipun ringkas itu berharga, kelengkapan lebih berharga. Meskipun nohup adalah GNU coreutil, jawaban bash-only (atau catatan tentang tidak ada) akan sesuai di sini. Jawaban yang bagus tetap saja. - Limited Atonement
nohuphanya mengabaikan SIGHUP sinyal. Ini menjalankan proses secara normal. Tidak ada daemonization. - nemo
@nemo Yang berarti prosesnya tidak terlepas, tetapi akan menjadi terpisah (dan anak dari init) jika kulitnya keluar ... kan? - Noldorin
@Noldorin Ya. Mengabaikan SIGHUP, yang dikirim ketika shell berakhir, akan membiarkan proses anak berjalan dan dipindahkan ke init. - nemo
@nemo nohup juga membungkam masuk / keluar standar. Menindaklanjuti dengan memungkiri untuk melepaskan sepenuhnya. - jiggunjer


Jika Anda menggunakan bash, coba disown [jobspec]; Lihat bash (1).

Pendekatan lain yang bisa Anda coba adalah at now. Jika Anda bukan superuser, izin Anda untuk menggunakannya at mungkin dibatasi.


51
2018-03-23 12:05



"disown" sepertinya bukan perintah bash internal (tidak tersedia di mesin saya, dan saya menggunakan bash). "nohup", seperti yang disarankan Ben, mungkin cara yang lebih baik (dan standar) untuk melakukan hal ini.
tidak pernah berpikir untuk menggunakan "pada", terima kasih untuk ide itu! - cadrian
at untuk mendelegasikan eksekusi kepada orang lain, saya menyukainya! +1 - Ninsuo
Sebagai titik acuan, ini berfungsi zsh demikian juga. - Coderer
Juga, disown tampaknya tidak memiliki efek yang diinginkan gnome-terminal-disownproses ed masih terbunuh ketika terminal keluar. Saya ingin tahu mengapa / bagaimana. - Kyle Strand


Membaca jawaban ini, saya berada di bawah kesan awal yang mengeluarkan nohup <command> & akan cukup. Menjalankan zsh di gnome-terminal, saya menemukan itu nohup <command> & tidak mencegah cangkang saya membunuh proses anak saat keluar. Meskipun nohup berguna, terutama dengan shell non-interaktif, hanya menjamin perilaku ini jika proses anak tidak mengatur ulang handler-nya untuk SIGHUP sinyal.

Dalam hal ini, nohup seharusnya mencegah sinyal hangup mencapai aplikasi, tetapi aplikasi anak (VMWare Player dalam kasus ini) mengatur ulang SIGHUP pawang Akibatnya ketika emulator terminal keluar, masih bisa membunuh subprocess Anda. Ini hanya dapat diselesaikan, sepengetahuan saya, dengan memastikan bahwa proses dihapus dari tabel pekerjaan shell. Jika nohup Ditimpa dengan shell builtin, seperti yang kadang-kadang terjadi, ini mungkin cukup, namun, jika tidak ...


disown adalah shell built in bash, zsh, dan ksh93,

<command> &
disown

atau

<command> &; disown

jika Anda lebih suka satu-liners. Ini memiliki efek yang umumnya diinginkan untuk menghapus subproses dari tabel pekerjaan. Ini memungkinkan Anda untuk keluar dari emulator terminal tanpa secara tidak sengaja menandakan proses anak sama sekali. Tidak peduli apa itu SIGHUP pawang terlihat seperti ini, ini seharusnya tidak membunuh proses anak Anda.

Setelah diingkari, prosesnya masih anak-anak dari emulator terminal Anda (mainkan dengan pstree jika Anda ingin menonton ini dalam aksi), tetapi setelah emulator terminal keluar, Anda harus melihatnya melekat pada proses init. Dengan kata lain, semuanya adalah sebagaimana mestinya, dan seperti yang Anda inginkan.

Apa yang harus dilakukan jika shell Anda tidak mendukung disown? Saya sangat menganjurkan untuk beralih ke salah satunya, tetapi tanpa pilihan itu, Anda memiliki beberapa pilihan.

  1. screen dan tmux dapat memecahkan masalah ini, tetapi mereka adalah solusi berat yang jauh lebih berat, dan saya tidak suka menjalankannya untuk tugas yang begitu sederhana. Mereka jauh lebih cocok untuk situasi di mana Anda ingin mempertahankan tty, biasanya pada mesin jarak jauh.
  2. Bagi banyak pengguna, mungkin diinginkan untuk melihat apakah shell Anda mendukung kemampuan seperti zsh setopt nohup. Ini dapat digunakan untuk menentukan itu SIGHUPtidak boleh dikirim ke pekerjaan di tabel pekerjaan ketika shell keluar. Anda dapat menerapkan ini sebelum keluar dari shell, atau menambahkannya ke konfigurasi shell seperti ~/.zshrc jika Anda selalu menginginkannya.
  3. Temukan cara untuk mengedit tabel pekerjaan. Saya tidak bisa menemukan cara untuk melakukan ini tcsh atau csh, yang agak mengganggu.
  4. Tuliskan program C kecil untuk melakukan off dan exec(). Ini adalah solusi yang sangat buruk, tetapi sumbernya hanya terdiri dari beberapa lusin garis. Anda kemudian dapat meneruskan perintah sebagai argumen baris perintah ke program C, dan dengan demikian menghindari entri khusus proses dalam tabel pekerjaan.

34
2018-01-22 17:08





  1. nohup $ COMMAND &

  2. $ COMMAND & disown

  3. perintah setid

Saya telah menggunakan nomor 2 untuk waktu yang sangat lama, tetapi nomor 3 juga berfungsi dengan baik. Juga, menyangkal memiliki bendera 'nohup' '-h', dapat menyangkal semua proses dengan '-a', dan dapat menyangkal semua proses yang berjalan dengan '-ar'.

Peredam dilakukan oleh '$ COMMAND &> / dev / null'.

Semoga ini membantu!


23
2017-08-25 14:39





Saya pikir layar mungkin memecahkan masalah Anda


9
2018-03-25 01:51





di tcsh (dan mungkin di shell lain juga), Anda dapat menggunakan tanda kurung untuk melepaskan proses.

Bandingkan ini:

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

Untuk ini:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

Ini menghapus firefox dari daftar pekerjaan, tetapi masih terikat ke terminal; jika Anda masuk ke node ini melalui 'ssh', mencoba logout akan tetap menggantung proses ssh.


8
2018-03-23 14:55





Untuk memisahkan perintah tty shell run melalui sub-shell untuk mis.

(perintah)&

Saat keluar digunakan terminal ditutup tetapi prosesnya masih hidup.

periksa -

(sleep 100) & exit

Buka terminal lain

ps aux | grep sleep

Proses masih hidup.


6
2017-08-07 05:18



Inilah yang saya butuhkan. Saya mencoba untuk menambahkan pintasan konsol untuk teks luhur dan itu bekerja dengan sempurna, inilah yang saya berakhir dengan: ("/ opt / Sublime Text 2 / sublime_text" $ @) & - Ron E


Jawaban paling sederhana dan hanya benar untuk bash:

command & disown

Anda tidak perlu melepaskan proses dari terminal, tetapi dari shell.


6
2018-05-05 11:55



Bekerja dengan sempurna. Terima kasih. - Royi