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 %1untuk pekerjaan pertama yang berjalan; cari nomor Anda dengan jobsperintah) sehingga pekerjaan tersebut tidak terbunuh saat terminal ditutup.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/… )
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
disownlepaskan semua pipa dari proses. Untuk memasang kembali pipa, gunakan gdbseperti 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:
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.
disown %1terminal pertama sebelum menutupnya.
kwinsetelah crash tanpa memikirkan konsekuensinya). Jadi, jika saya berhenti kwin, semuanya akan membeku dan saya tidak memiliki kemungkinan untuk lari bg!
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.
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.
Isu:
% jobs
[1] running java
[2] suspended vi
% disown %1
Lihat http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ untuk diskusi lebih rinci tentang Kontrol Pekerjaan Unix.
Sayangnya disownkhusus untuk bash dan tidak tersedia di semua shell.
Rasa Unix tertentu (misalnya AIX dan Solaris) memiliki opsi pada nohupperintah itu sendiri yang dapat diterapkan untuk proses yang berjalan:
nohup -p pid
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
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_RDWR O_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:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
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> 0 11: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> 0 11: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> 1 0 11:16 ? S 0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey 0u CHR 136,36 38 /dev/pts/36 (deleted)
loop.sh <PID> truey 1u REG 0,26 1127 15008411 /home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,36 38 /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:
call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit
Atau seseorang dapat menggunakan liner berikut sebagai gantinya:
gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
Saya harap ini adalah deskripsi solusi yang cukup lengkap.
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.
Untuk mengirim proses yang sedang berjalan ke nohup ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid , itu tidak berhasil untuk saya
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.
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).
Ini bekerja untuk saya di Ubuntu linux saat di tcshell.
CtrlZ untuk menghentikannya
bg untuk berjalan di latar belakang
jobs untuk mendapatkan nomor pekerjaannya
nohup %n di mana n adalah nomor pekerjaan
nohup: failed to run command '%1': No such file or directory
yourExecutable &dan output terus muncul di layar danCtrl+Ctampaknya tidak menghentikan apa pun, ketik saja secara membabi butadisown;dan tekanEnterbahkan 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.