Untuk siapa pun yang menghadapi masalah yang sama: Ingat, bahwa bahkan jika Anda mengetik yourExecutable &dan output terus muncul di layar dan Ctrl+Ctampaknya tidak menghentikan apa pun, ketik saja secara membabi buta disown;dan tekan Enterbahkan jika layar bergulir dengan output dan Anda tidak dapat melihat apa Anda sedang mengetik. Proses ini akan ditolak dan Anda akan dapat menutup terminal tanpa proses sekarat.
Nav
Jawaban:
1367
Menggunakan Kontrol Pekerjaan bash untuk mengirim proses ke latar belakang:
Ctrl+ Zuntuk menghentikan (menghentikan sementara) program dan kembali ke shell.
bg untuk menjalankannya di latar belakang.
disown -h [job-spec]di mana [job-spec] adalah nomor pekerjaan (seperti %1untuk pekerjaan pertama yang berjalan; cari nomor Anda dengan jobsperintah) sehingga pekerjaan tersebut tidak terbunuh saat terminal ditutup.
Karena pertanyaannya adalah bagaimana "meletakkannya di bawah nohup", disown -hmungkin adalah jawaban yang lebih tepat: "membuat disown bersikap lebih seperti nohup (yaitu pekerjaan akan tetap berada di pohon proses shell Anda saat ini sampai Anda keluar dari shell Anda) Ini memungkinkan Anda untuk melihat semua pekerjaan yang dimulai shell ini. " (dari [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )
Dr. Jan-Philip Gehrcke
8
Bagaimana saya memulihkan pekerjaan nanti? Saya bisa melihatnya berjalan menggunakan ps -e.
Paulo Casaretto
26
Anda tidak dapat melihat output dari suatu pekerjaan setelah a disown, disown menjadikan sebuah proses daemon, yang berarti input / output standar dialihkan ke / dev / null. Jadi, jika Anda berencana untuk menolak suatu pekerjaan, lebih baik memulainya dengan masuk ke file, misalnyamy_job_command | tee my_job.log
rustyx
8
apakah mungkin untuk melakukan sesuatu seperti 'my_job_command | tee my_job.log ' setelah perintah sudah berjalan?
arod
23
disownlepaskan semua pipa dari proses. Untuk memasang kembali pipa, gunakan gdbseperti yang dijelaskan di utas ini . Lebih khusus lagi, posting ini .
mbrownnyc
185
Misalkan karena beberapa alasan Ctrl+ Zjuga tidak berfungsi, pergi ke terminal lain, cari id proses (menggunakan ps) dan jalankan:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOPakan menunda proses dan SIGCONTakan melanjutkan proses, di latar belakang. Jadi sekarang, menutup kedua terminal Anda tidak akan menghentikan proses Anda.
Ya, itu masalah OS, kill tidak bekerja dengan Cygwin di Windows.
Pungs
6
Juga sangat berguna jika pekerjaan dimulai dari sesi ssh lain.
Amir Ali Akbari
5
Ingatlah untuk melakukan disown %1terminal pertama sebelum menutupnya.
fred
1
Ini berguna karena saya memulai antarmuka grafis dengan konsol (dalam kasus saya, saya mulai dari konsole kwinsetelah crash tanpa memikirkan konsekuensinya). Jadi, jika saya berhenti kwin, semuanya akan membeku dan saya tidak memiliki kemungkinan untuk lari bg!
Michele
@ Fred Saya tidak melakukan ini dan sepertinya terus berjalan. Kemungkinan atau apakah saya menekan PID yang salah?
Tidak ada yang
91
Perintah untuk memisahkan pekerjaan yang sedang berjalan dari shell (= membuatnya nohup) adalah disowndan perintah dasar shell.
Dari bash-manpage (man bash):
menolak [-ar] [-h] [jobspec ...]
Tanpa opsi, setiap jobspec dihapus dari tabel pekerjaan aktif. Jika opsi -h diberikan, setiap jobspec tidak dihapus dari tabel, tetapi ditandai sehingga SIGHUP tidak dikirim ke pekerjaan jika shell menerima SIGHUP. Jika tidak ada jobspec, dan opsi -a atau -r tidak disediakan, pekerjaan saat ini digunakan. Jika tidak ada jobspec yang disediakan, opsi -a berarti menghapus atau menandai semua pekerjaan; opsi -r tanpa argumen jobspec membatasi operasi untuk menjalankan pekerjaan. Nilai pengembaliannya adalah 0 kecuali jika suatu jobspec tidak menentukan pekerjaan yang valid.
Itu artinya, itu sederhana
disown -a
akan menghapus semua pekerjaan dari tabel pekerjaan dan membuatnya tidak ada
disown -amenghapus semua pekerjaan. Sederhana disownhanya menghilangkan pekerjaan saat ini. Seperti halaman manual dalam jawaban mengatakan.
Rune Schjellerup Philosof
73
Ini adalah jawaban yang bagus di atas, saya hanya ingin menambahkan klarifikasi:
Anda tidak dapat disownmelakukan pid atau proses, Anda disownpekerjaan, dan itu adalah perbedaan penting.
Pekerjaan adalah sesuatu yang merupakan gagasan tentang proses yang melekat pada shell, oleh karena itu Anda harus membuang pekerjaan ke latar belakang (tidak menangguhkannya) dan kemudian menolaknya.
Hanya untuk AIXdan Solaris. "Versi nohup AIX dan Solaris memiliki opsi -p yang memodifikasi proses yang berjalan untuk mengabaikan sinyal SIGHUP masa depan. Tidak seperti bawaan yang dijelaskan di atas yang dibangun oleh bash, nohup -p menerima ID proses.". Sumber
AlikElzin-kilaka
27
Jawaban Node benar-benar hebat, tetapi tetap membuka pertanyaan bagaimana stdout dan stderr diarahkan. Saya menemukan solusi di Unix & Linux , tetapi juga tidak lengkap. Saya ingin menggabungkan dua solusi ini. Ini dia:
Untuk pengujian saya, saya membuat skrip bash kecil yang disebut loop.sh, yang mencetak pid itu sendiri dengan tidur sebentar dalam loop tak terbatas.
$./loop.sh
Sekarang dapatkan PID dari proses ini entah bagaimana. Biasanya ps -C loop.shcukup baik, tetapi dicetak dalam kasus saya.
Sekarang kita dapat beralih ke terminal lain (atau tekan ^ Z dan di terminal yang sama). Sekarang gdbharus dilampirkan ke proses ini.
$ gdb -p <PID>
Ini menghentikan skrip (jika berjalan). Keadaannya dapat diperiksa oleh ps -f <PID>, di mana STATbidangnya adalah 'T +' (atau dalam kasus ^ Z 'T'), yang artinya (man ps (1))
T Stopped, either by a job control signal or because it is being traced
+ is in the foreground process group
(gdb) call close(1)
$1 =0
Tutup (1) mengembalikan nol jika berhasil.
(gdb) call open("loop.out",01102,0600)
$6 =1
Buka (1) mengembalikan deskriptor file baru jika berhasil.
Terbuka ini sama dengan open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). Alih-alih O_RDWRO_WRONLYbisa diterapkan, tetapi /usr/sbin/lsofmengatakan 'u' untuk semua penangan file std * ( FDkolom), yaitu O_RDWR.
Saya memeriksa nilai di file header /usr/include/bits/fcntl.h.
File output dapat dibuka dengan O_APPEND, seperti yang nohupakan dilakukan, tetapi ini tidak disarankan oleh man open(2), karena kemungkinan masalah NFS.
Jika kita mendapatkan -1 sebagai nilai kembali, lalu call perror("")mencetak pesan kesalahan. Jika kita membutuhkan errno, gunakan p errnoperintah gdb.
Sekarang kita dapat memeriksa file yang baru diarahkan. /usr/sbin/lsof -p <PID>cetakan:
Jika kita mau, kita dapat mengarahkan stderr ke file lain, jika kita ingin menggunakan call close(2)dan call open(...)lagi menggunakan nama file yang berbeda.
Sekarang yang terlampir bashharus dilepaskan dan kita dapat berhenti gdb:
(gdb) detach
Detaching from program:/bin/bash, process <PID>(gdb) q
Jika skrip dihentikan oleh gdbdari terminal lain itu terus berjalan. Kita dapat beralih kembali ke terminal loop.sh. Sekarang tidak menulis apa pun ke layar, tetapi menjalankan dan menulis ke dalam file. Kita harus meletakkannya di latar belakang. Jadi tekan ^Z.
^Z
[1]+Stopped./loop.sh
(Sekarang kita berada dalam kondisi yang sama seolah-olah ^Zditekan di awal.)
Sekarang kita dapat memeriksa status pekerjaan:
$ ps -f 24522
UID PID PPID C STIME TTY STAT TIME CMD
<UID><PID><PPID>011:16 pts/36 S 0:00/bin/bash ./loop.sh
$ jobs
[1]+Stopped./loop.sh
Jadi proses harus berjalan di latar belakang dan terlepas dari terminal. Angka dalam jobsoutput perintah dalam tanda kurung mengidentifikasi pekerjaan di dalam bash. Kita bisa menggunakan bashperintah bawaan berikut yang menerapkan tanda '%' sebelum nomor pekerjaan:
$ bg %1[1]+./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID><PID><PPID>011:16 pts/36 S 0:00/bin/bash ./loop.sh
Dan sekarang kita bisa berhenti dari bash panggilan. Proses terus berjalan di latar belakang. Jika kita menghentikan PPID-nya menjadi proses 1 (init (1)) dan terminal kontrol menjadi tidak dikenal.
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID><PID>1011:16? S 0:00/bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>...
loop.sh <PID> truey 0u CHR 136,3638/dev/pts/36(deleted)
loop.sh <PID> truey 1u REG 0,26112715008411/home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,3638/dev/pts/36(deleted)
KOMENTAR
Hal-hal gdb dapat secara otomatis membuat file (misalnya loop.gdb) yang berisi perintah dan jalankan gdb -q -x loop.gdb -p <PID>. Loop.gdb saya terlihat seperti ini:
Memang sangat informatif, dan kemungkinan akan bekerja dengan baik dalam kasus-kasus sederhana. Tetapi berhati-hatilah, kasus yang lebih kompleks mungkin gagal total. Saya memiliki salah satu dari itu hari ini: Proses saya telah menghasilkan proses lain yang menghasilkan output (mungkin untuk stderr), tetapi tetap terhubung untuk berkomunikasi dengan tuannya. Mengarahkan FD tuan tidak efektif karena anak itu mewarisi stderr, dan menutup anak-anak itu gagal membuat master yang menunggu di ujung pipa yang lain. X- | Bettern tahu proses Anda dengan baik sebelum Anda mencoba ini.
cmaster - mengembalikan monica
@ cmaster Anda dapat memeriksa apakah sebuah pegangan dialihkan menggunakan lsof(nama file menangani adalah pipetidak suka /dev/pts/1) atau dengan ls -l /proc/<PID>/fd/<fd>(ini menunjukkan symlink dari pegangan). Selain itu, subproses masih belum dapat mengalihkan keluaran, yang harus diarahkan ke file.
Kemudian saya mencoba perintah berikut dan itu bekerja dengan sangat baik
Jalankan beberapa SOMECOMMAND, katakanlah /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.
Ctrl+ Zuntuk menghentikan (menghentikan sementara) program dan kembali ke shell.
bg untuk menjalankannya di latar belakang.
disown -h sehingga proses tidak terbunuh saat terminal ditutup.
Ketik exituntuk keluar dari shell karena sekarang Anda baik untuk pergi karena operasi akan berjalan di latar belakang dalam prosesnya sendiri, sehingga tidak terkait dengan shell.
Proses ini setara dengan berjalan nohup SOMECOMMAND.
Ini bekerja dengan baik. Itu terus menjalankan proses saya bahkan setelah menutup terminal windows. Kami memiliki ksh sebagai shell default sehingga perintah bgdan disowntidak bekerja.
Saya pikir perilaku untuk dipungkiri -a adalah memotong keterikatan dengan semua pekerjaan. Namun, itu tidak mematikan pipa stdin / stdout, yang berarti bahwa proses tersebut masih akan mencoba untuk menulis (/ membaca) dari terminal
Kelthar
-2
Ini bekerja untuk saya di Ubuntu linux saat di tcshell.
yourExecutable &
dan output terus muncul di layar danCtrl+C
tampaknya tidak menghentikan apa pun, ketik saja secara membabi butadisown;
dan tekanEnter
bahkan jika layar bergulir dengan output dan Anda tidak dapat melihat apa Anda sedang mengetik. Proses ini akan ditolak dan Anda akan dapat menutup terminal tanpa proses sekarat.Jawaban:
Menggunakan Kontrol Pekerjaan bash untuk mengirim proses ke latar belakang:
bg
untuk menjalankannya di latar belakang.disown -h [job-spec]
di mana [job-spec] adalah nomor pekerjaan (seperti%1
untuk pekerjaan pertama yang berjalan; cari nomor Anda denganjobs
perintah) sehingga pekerjaan tersebut tidak terbunuh saat terminal ditutup.sumber
disown -h
mungkin adalah jawaban yang lebih tepat: "membuat disown bersikap lebih seperti nohup (yaitu pekerjaan akan tetap berada di pohon proses shell Anda saat ini sampai Anda keluar dari shell Anda) Ini memungkinkan Anda untuk melihat semua pekerjaan yang dimulai shell ini. " (dari [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )disown
, disown menjadikan sebuah proses daemon, yang berarti input / output standar dialihkan ke / dev / null. Jadi, jika Anda berencana untuk menolak suatu pekerjaan, lebih baik memulainya dengan masuk ke file, misalnyamy_job_command | tee my_job.log
disown
lepaskan semua pipa dari proses. Untuk memasang kembali pipa, gunakangdb
seperti yang dijelaskan di utas ini . Lebih khusus lagi, posting ini .Misalkan karena beberapa alasan Ctrl+ Zjuga tidak berfungsi, pergi ke terminal lain, cari id proses (menggunakan
ps
) dan jalankan:SIGSTOP
akan menunda proses danSIGCONT
akan melanjutkan proses, di latar belakang. Jadi sekarang, menutup kedua terminal Anda tidak akan menghentikan proses Anda.sumber
disown %1
terminal pertama sebelum menutupnya.kwin
setelah crash tanpa memikirkan konsekuensinya). Jadi, jika saya berhenti kwin, semuanya akan membeku dan saya tidak memiliki kemungkinan untuk laribg
!Perintah untuk memisahkan pekerjaan yang sedang berjalan dari shell (= membuatnya nohup) adalah
disown
dan perintah dasar shell.Dari bash-manpage (man bash):
Itu artinya, itu sederhana
akan menghapus semua pekerjaan dari tabel pekerjaan dan membuatnya tidak ada
sumber
disown -a
menghapus semua pekerjaan. Sederhanadisown
hanya menghilangkan pekerjaan saat ini. Seperti halaman manual dalam jawaban mengatakan.Ini adalah jawaban yang bagus di atas, saya hanya ingin menambahkan klarifikasi:
Anda tidak dapat
disown
melakukan pid atau proses, Andadisown
pekerjaan, dan itu adalah perbedaan penting.Pekerjaan adalah sesuatu yang merupakan gagasan tentang proses yang melekat pada shell, oleh karena itu Anda harus membuang pekerjaan ke latar belakang (tidak menangguhkannya) dan kemudian menolaknya.
Isu:
Lihat http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ untuk diskusi lebih rinci tentang Kontrol Pekerjaan Unix.
sumber
Sayangnya
disown
khusus untuk bash dan tidak tersedia di semua shell.Rasa Unix tertentu (misalnya AIX dan Solaris) memiliki opsi pada
nohup
perintah itu sendiri yang dapat diterapkan untuk proses yang berjalan:Lihat http://en.wikipedia.org/wiki/Nohup
sumber
AIX
danSolaris
. "Versi nohup AIX dan Solaris memiliki opsi -p yang memodifikasi proses yang berjalan untuk mengabaikan sinyal SIGHUP masa depan. Tidak seperti bawaan yang dijelaskan di atas yang dibangun oleh bash, nohup -p menerima ID proses.". SumberJawaban Node benar-benar hebat, tetapi tetap membuka pertanyaan bagaimana stdout dan stderr diarahkan. Saya menemukan solusi di Unix & Linux , tetapi juga tidak lengkap. Saya ingin menggabungkan dua solusi ini. Ini dia:
Untuk pengujian saya, saya membuat skrip bash kecil yang disebut loop.sh, yang mencetak pid itu sendiri dengan tidur sebentar dalam loop tak terbatas.
Sekarang dapatkan PID dari proses ini entah bagaimana. Biasanya
ps -C loop.sh
cukup baik, tetapi dicetak dalam kasus saya.Sekarang kita dapat beralih ke terminal lain (atau tekan ^ Z dan di terminal yang sama). Sekarang
gdb
harus dilampirkan ke proses ini.Ini menghentikan skrip (jika berjalan). Keadaannya dapat diperiksa oleh
ps -f <PID>
, di manaSTAT
bidangnya adalah 'T +' (atau dalam kasus ^ Z 'T'), yang artinya (man ps (1))Tutup (1) mengembalikan nol jika berhasil.
Buka (1) mengembalikan deskriptor file baru jika berhasil.
Terbuka ini sama dengan
open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
. Alih-alihO_RDWR
O_WRONLY
bisa diterapkan, tetapi/usr/sbin/lsof
mengatakan 'u' untuk semua penangan file std * (FD
kolom), yaituO_RDWR
.Saya memeriksa nilai di file header /usr/include/bits/fcntl.h.
File output dapat dibuka dengan
O_APPEND
, seperti yangnohup
akan dilakukan, tetapi ini tidak disarankan olehman open(2)
, karena kemungkinan masalah NFS.Jika kita mendapatkan -1 sebagai nilai kembali, lalu
call perror("")
mencetak pesan kesalahan. Jika kita membutuhkan errno, gunakanp errno
perintah gdb.Sekarang kita dapat memeriksa file yang baru diarahkan.
/usr/sbin/lsof -p <PID>
cetakan:Jika kita mau, kita dapat mengarahkan stderr ke file lain, jika kita ingin menggunakan
call close(2)
dancall open(...)
lagi menggunakan nama file yang berbeda.Sekarang yang terlampir
bash
harus dilepaskan dan kita dapat berhentigdb
:Jika skrip dihentikan oleh
gdb
dari terminal lain itu terus berjalan. Kita dapat beralih kembali ke terminal loop.sh. Sekarang tidak menulis apa pun ke layar, tetapi menjalankan dan menulis ke dalam file. Kita harus meletakkannya di latar belakang. Jadi tekan^Z
.(Sekarang kita berada dalam kondisi yang sama seolah-olah
^Z
ditekan di awal.)Sekarang kita dapat memeriksa status pekerjaan:
Jadi proses harus berjalan di latar belakang dan terlepas dari terminal. Angka dalam
jobs
output perintah dalam tanda kurung mengidentifikasi pekerjaan di dalambash
. Kita bisa menggunakanbash
perintah bawaan berikut yang menerapkan tanda '%' sebelum nomor pekerjaan:Dan sekarang kita bisa berhenti dari bash panggilan. Proses terus berjalan di latar belakang. Jika kita menghentikan PPID-nya menjadi proses 1 (init (1)) dan terminal kontrol menjadi tidak dikenal.
KOMENTAR
Hal-hal gdb dapat secara otomatis membuat file (misalnya loop.gdb) yang berisi perintah dan jalankan
gdb -q -x loop.gdb -p <PID>
. Loop.gdb saya terlihat seperti ini:Atau seseorang dapat menggunakan liner berikut sebagai gantinya:
Saya harap ini adalah deskripsi solusi yang cukup lengkap.
sumber
lsof
(nama file menangani adalahpipe
tidak suka/dev/pts/1
) atau denganls -l /proc/<PID>/fd/<fd>
(ini menunjukkan symlink dari pegangan). Selain itu, subproses masih belum dapat mengalihkan keluaran, yang harus diarahkan ke file.Untuk mengirim proses yang sedang berjalan ke nohup ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid
, itu tidak berhasil untuk sayaKemudian saya mencoba perintah berikut dan itu bekerja dengan sangat baik
Jalankan beberapa SOMECOMMAND, katakanlah
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.Ctrl+ Zuntuk menghentikan (menghentikan sementara) program dan kembali ke shell.
bg
untuk menjalankannya di latar belakang.disown -h
sehingga proses tidak terbunuh saat terminal ditutup.Ketik
exit
untuk keluar dari shell karena sekarang Anda baik untuk pergi karena operasi akan berjalan di latar belakang dalam prosesnya sendiri, sehingga tidak terkait dengan shell.Proses ini setara dengan berjalan
nohup SOMECOMMAND
.sumber
Pada sistem AIX saya, saya mencoba
Ini bekerja dengan baik. Itu terus menjalankan proses saya bahkan setelah menutup terminal windows. Kami memiliki ksh sebagai shell default sehingga perintah
bg
dandisown
tidak bekerja.sumber
bg
- ini akan menempatkan pekerjaan di latar belakang dan kembali dalam proses yang berjalandisown -a
- ini akan memotong semua lampiran dengan pekerjaan (sehingga Anda dapat menutup terminal dan itu akan tetap berjalan)Langkah-langkah sederhana ini akan memungkinkan Anda untuk menutup terminal sambil menjaga proses tetap berjalan.
Itu tidak akan memakai
nohup
(berdasarkan pemahaman saya tentang pertanyaan Anda, Anda tidak membutuhkannya di sini).sumber
Ini bekerja untuk saya di Ubuntu linux saat di tcshell.
CtrlZ untuk menghentikannya
bg
untuk berjalan di latar belakangjobs
untuk mendapatkan nomor pekerjaannyanohup %n
di mana n adalah nomor pekerjaansumber
nohup: failed to run command '%1': No such file or directory