Pertanyaan Bagaimana cara saya menempatkan proses yang sudah berjalan di bawah nohup?


Saya memiliki proses yang sudah berjalan sejak lama dan tidak ingin mengakhirinya.

Bagaimana saya meletakkannya di bawah nohup (yaitu, bagaimana saya menyebabkannya terus berjalan bahkan jika saya menutup terminal?)


775
2018-03-09 08:33


asal


Jawaban:


Menggunakan Kontrol Pekerjaan bash untuk mengirim proses ke latar belakang:

  1. Ctrl+Z untuk menghentikan (jeda) program dan kembali ke shell.
  2. bg untuk menjalankannya di latar belakang.
  3. disown -h [job-spec] di mana [spesifikasi pekerjaan] adalah nomor pekerjaan (seperti %1 untuk pekerjaan pertama yang dijalankan; temukan nomor Anda dengan jobs perintah) sehingga pekerjaan tidak terbunuh ketika terminal ditutup.

1153
2018-03-09 08:41



Misalkan untuk beberapa alasan Ctrl+Z juga tidak berfungsi, pergi ke terminal lain, cari id proses (menggunakan ps) dan lari:

kill -20 PID 
kill -18 PID

kill -20 (SIGTSTP) akan menangguhkan proses dan kill -18 (SIGCONT) akan melanjutkan proses, di latar belakang. Jadi sekarang, menutup kedua terminal Anda tidak akan menghentikan proses Anda.


141
2018-04-23 08:01



Perintah untuk memisahkan pekerjaan yang berjalan dari shell (= membuatnya nohup) adalah disown dan perintah shell dasar.

Dari bash-manpage (man bash):

memungkiri [-ar] [-h] [jobspec ...]

Tanpa opsi, setiap jobspec dihapus dari tabel pekerjaan aktif. Jika opsi -h diberikan, masing-masing jobspec tidak   dihapus dari tabel, tetapi ditandai agar SIGHUP tidak dikirim ke pekerjaan jika shell menerima SIGHUP. Jika tidak ada jobspec   hadir, dan baik opsi -a maupun opsi -r diberikan, pekerjaan saat ini digunakan. Jika tidak ada jobspec disediakan, opsi -a   berarti menghapus atau menandai semua pekerjaan; opsi -r tanpa argumen jobspec membatasi operasi untuk menjalankan pekerjaan. Kembalinya   nilainya adalah 0 kecuali jobspec tidak menentukan pekerjaan yang valid.

Itu artinya, itu sederhana

disown -a

akan menghapus semua pekerjaan dari meja kerja dan membuat mereka nohup


72
2018-03-09 08:38



Ini adalah jawaban yang bagus di atas, saya hanya ingin menambahkan klarifikasi:

Anda tidak bisa disown sebuah pid atau proses, Anda disown pekerjaan, dan itu adalah perbedaan penting.

Pekerjaan adalah sesuatu yang merupakan gagasan proses yang dilekatkan pada shell, oleh karena itu Anda harus membuang pekerjaan ke latar belakang (bukan 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 Pengontrolan Pekerjaan Unix.


60
2017-11-19 15:48



Sial sayang disown khusus untuk bash dan tidak tersedia di semua cangkang.

Citarasa tertentu dari Unix (mis. AIX dan Solaris) memiliki opsi di nohup perintah itu sendiri yang dapat diterapkan pada proses yang sedang berjalan:

nohup -p pid

Lihat http://en.wikipedia.org/wiki/Nohup


36
2018-03-16 23:49



Jawaban Node benar-benar hebat, tetapi itu membiarkan pertanyaan terbuka bagaimana caranya mendapatkan stdout dan stderr dialihkan. Saya menemukan solusi Unix & Linux, tetapi itu juga tidak lengkap. Saya ingin menggabungkan kedua solusi ini. Ini dia:

Untuk pengujian saya, saya membuat skrip bash kecil yang disebut loop.sh, yang mencetak pid dari dirinya sendiri dengan satu menit tidur dalam loop tak terbatas.

$./loop.sh

Sekarang dapatkan PID dari proses ini bagaimanapun juga. Biasanya ps -C loop.sh cukup bagus, tetapi dicetak dalam kasus saya.

Sekarang kita dapat beralih ke terminal lain (atau tekan ^ Z dan di terminal yang sama). Sekarang gdb harus dilampirkan pada proses ini.

$ gdb -p <PID>

Ini menghentikan skrip (jika dijalankan). Keadaannya dapat diperiksa oleh ps -f <PID>, Dimana STAT field is 'T +' (atau dalam kasus ^ Z 'T'), yang berarti (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 pada keberhasilan.

(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). Dari pada O_RDWR  O_WRONLY bisa diterapkan, tapi /usr/sbin/lsof mengatakan 'u' untuk semua penangan file std * (FD kolom), yang mana O_RDWR.

Saya memeriksa nilai-nilai di file header /usr/include/bits/fcntl.h.

File output bisa dibuka dengan O_APPEND, sebagai nohup akan melakukannya, tetapi ini tidak disarankan oleh man open(2), karena kemungkinan masalah NFS.

Jika kita mendapatkan -1 sebagai nilai kembali, maka call perror("") mencetak pesan kesalahan. Jika kita membutuhkan errno, gunakan p errno perintah 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 mengalihkan stderr ke file lain, jika kita ingin menggunakannya call close(2) dan call open(...) lagi menggunakan nama file yang berbeda.

Sekarang yang terlampir bash harus dibebaskan dan kita bisa berhenti gdb:

(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q

Jika skrip dihentikan oleh gdb dari terminal lain terus berjalan. Kita dapat beralih kembali ke terminal loop.sh. Sekarang itu tidak menulis apa pun ke layar, tetapi berjalan dan menulis ke file. Kami harus meletakkannya di latar belakang. Jadi tekan ^Z.

^Z
[1]+  Stopped                 ./loop.sh

(Sekarang kita berada dalam kondisi yang sama ^Z ditekan di awal.)

Sekarang kita dapat memeriksa keadaan 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 jobs output perintah dalam tanda kurung siku mengidentifikasi pekerjaan di dalamnya bash. Kita dapat menggunakan yang berikut ini bash perintah 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 keluar dari pesta panggilan. Proses terus berjalan di latar belakang. Jika kita keluar dari PPID-nya menjadi 1 (proses 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

Gdb stuff dapat diotomatisasi membuat file (misalnya loop.gdb) yang berisi perintah dan dijalankan 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 orang dapat menggunakan satu liner sebagai berikut:

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.


21
2017-10-10 09:35



Untuk mengirim proses yang berjalan ke nohup (http://en.wikipedia.org/wiki/Nohup)

nohup -p pid , itu tidak berhasil untukku

Lalu saya mencoba perintah berikut dan bekerja dengan sangat baik

  1. Jalankan beberapa SOMECOMMAND, mengatakan /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Ctrl+Z untuk menghentikan (jeda) program dan kembali ke shell.

  3. bg untuk menjalankannya di latar belakang.

  4. disown -h sehingga prosesnya tidak terbunuh ketika terminal ditutup.

  5. Mengetik exit untuk keluar dari shell karena sekarang Anda baik untuk pergi karena operasi akan berjalan di latar belakang dalam prosesnya sendiri, jadi tidak terikat dengan shell.

Proses ini sama dengan menjalankan nohup SOMECOMMAND.


6
2017-09-27 06:48



Pada sistem AIX saya, saya mencoba

nohup -p  processid>

Ini bekerja dengan baik. Ini terus menjalankan proses saya bahkan setelah menutup jendela terminal. Kami memiliki ksh sebagai shell default jadi bg dan disown perintah tidak berfungsi.


1
2018-03-03 16:16



  1. ctrl + z  - ini akan menghentikan sementara pekerjaan (tidak akan dibatalkan!)
  2. bg - ini akan menempatkan pekerjaan di latar belakang dan kembali dalam proses yang sedang berjalan
  3. disown -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 dipakai nohup (berdasarkan pemahaman saya tentang pertanyaan Anda, Anda tidak membutuhkannya di sini).


1
2018-03-24 17:06



Ini bekerja untuk saya di Ubuntu linux sementara di tcshell.

  1. CtrlZ untuk menghentikannya

  2. bg untuk berjalan di latar belakang

  3. jobs untuk mendapatkan nomor pekerjaannya

  4. nohup %n dimana n adalah nomor pekerjaan


0
2017-08-04 22:57