Cara benar-benar bercabang perintah shell yang menggunakan pengalihan

13

Saya telah menulis beberapa skrip shell selama bertahun-tahun (tapi saya jelas bukan sysadmin) dan ada sesuatu yang selalu menyebabkan saya bermasalah: bagaimana saya bisa membuat perintah shell yang kebal terhadap hangup di latar belakang dari skrip Bash ?

Sebagai contoh jika saya memiliki ini:

command_which_takes_time input > output

Bagaimana saya bisa "nohup" dan memotong ini?

Tampaknya ini tidak melakukan apa yang saya inginkan:

nohup command_which_takes_time input > output &

Apa sintaks yang saya cari dan apa yang tidak saya mengerti?

Cedric Martin
sumber

Jawaban:

13

Coba buat subkulit dengan (...):

( command_which_takes_time input > output ) &

Contoh:

~$ ( (sleep 10; date) > /tmp/q ) &
[1] 19521
~$ cat /tmp/q # ENTER
~$ cat /tmp/q # ENTER
(...) #AFTER 10 seconds
~$ cat /tmp/q #ENTER
Wed Jan 11 01:35:55 CET 2012
[1]+  Done                    ( ( sleep 10; date ) > /tmp/q )
Grzegorz Wierzowiecki
sumber
18

Kamu harus mencoba setsid(1). Gunakan seperti yang Anda gunakan nohup:

setsid command_which_takes_time input > output

Ini (sesuai halaman setsid(2)manual), melakukan a fork(2), an _exit(2)dari proses induk, kemudian proses anak memanggil setsid(2)untuk membuat grup proses baru (sesi).

Anda tidak dapat membunuh itu dengan keluar, dan itu bukan bagian dari kontrol pekerjaan Bash shebang. Untuk semua maksud dan tujuan, ini adalah dasmon yang tepat.

Alexios
sumber
4

ada disownperintah bash builtin:

[1] 9180
root@ntb1:~# jobs
[1]+  Running                 sleep 120 &
root@ntb1:~# disown
root@ntb1:~# jobs
... no jobs, disowned
root@ntb1:~# ps aux | grep sleep | grep -v grep
root      9180  0.0  0.0   4224   284 pts/0    S    17:55   0:00 sleep 120
... but the sleep still runing
root@ntb1:~#

Setelah disown , pekerjaan itu dikeluarkan dari shell Anda (sehingga Anda bahkan dapat keluar) dan masih tetap berjalan sampai selesai.

Lihat jobsperintah 1 yang terdaftar sleepnamun ke-2 jobssetelah penolakan tidak. Tetapi dengan menggunakan pskita dapat melihat bahwa pekerjaan itu masih berjalan.

Daniel Péder
sumber
2

Freebsd:

/usr/sbin/daemon -f <command> <command args>
h0tw1r3
sumber
-2

Ini akan berfungsi (jangan ketik spasi tambahan):

command &>output.file
David
sumber
1
Ini sepertinya tidak ada hubungannya dengan pertanyaan, karena tidak bercabang atau mencapai yang setara nohup.
Dan Getz