Bagaimana saya bisa melepaskan proses dari skrip bash?

18

Saya mencoba untuk melepaskan proses dari skrip bash sehingga SIGINT tidak akan diteruskan ke proses ketika saya keluar dari skrip.

Saya telah menggunakan disownperintah di terminal secara langsung, namun dalam bash, disowntidak menghentikan SIGINT agar tidak diteruskan. Tujuan dari skrip ini adalah untuk memulai openocd dan kemudian gdb dengan doa tunggal. Karena skrip tidak pernah keluar (itu menjalankan gdb) SIGINT masih diteruskan dari gdb ke openocd yang merupakan masalah karena SIGINT digunakan sebagai perintah berhenti di gdb.

Di terminal akan terlihat seperti ini:

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

ketika dipanggil pada terminal dalam urutan ini, SIGINT tidak diteruskan dari gdb ke openocd. Namun jika doa yang sama ini dalam skrip bash, SIGINT diteruskan.

Bantuan apa pun akan sangat dihargai.

ps masalah ini ada di OS X tapi saya mencoba menggunakan alat yang juga portabel untuk semua alat Unix.

pengguna2328113
sumber
nohupbukan jawaban yang tepat. Anda harus menambahkan beberapa pseudocode atau kode contoh untuk menunjukkan lebih tepat apa yang Anda inginkan.
Bruce Ediger
1
Apakah Anda terbuka untuk menggunakan alat seperti screen?
Eric Renouf

Jawaban:

17

Untuk melepaskan proses dari skrip bash:

nohup ./process &

Jika Anda menghentikan skrip bash Anda dengan SIGINT(ctrl + c), atau shell keluar dari pengiriman SIGHUPmisalnya, prosesnya tidak akan terganggu dan akan melanjutkan eksekusi secara normal. stdout& stderrAkan diarahkan ke sebuah file log: nohup.out.

Jika Anda ingin mengeksekusi perintah yang terpisah sementara dapat melihat output di terminal, maka gunakan tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &
marc
sumber
Mengapa nohupnecassary? Apa perbedaan antara nohup COMMAND &dan COMMAND &jika tujuan Anda hanya menjalankan perintah di latar belakang dan membebaskan terminal?
James Wierzba
@ JamesWierzba Salah satu perbedaannya adalah bahwa jika Anda memerlukan perintah untuk terus berjalan bahkan setelah keluar dari shell, maka nohup adalah cara untuk melakukannya. Ada ribuan penjelasan luas di web. Misalnya stackoverflow.com/questions/15595374/…
marc
10

Bagi saya ini berfungsi dengan baik dengan disown

command & disown
ManuelSchneid3r
sumber
4

Solusi yang saya temukan melibatkan sebuah program yang disebut 'detach' yang ditulis oleh Annon Inglorion dan dapat diunduh dari situs webnya

Setelah dikompilasi, dapat digunakan dalam skrip sebagai berikut:

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

Baris pertama ini menciptakan proses baru (menjalankan openocd) dan menyimpan id proses dalam file (debug.pid) untuk digunakan nanti. Ini mencegah masalah dengan menangkap pid seperti yang disediakan dalam jawaban Oliver. Setelah keluar dari program pemblokiran berikutnya (gdb) file yang menyimpan pid digunakan untuk membunuh proses yang terlepas secara langsung.

pengguna2328113
sumber
Dapat mengkonfirmasi, detachmembuat keajaiban.
AS
2

solusi sederhana dan portabel:

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

Beberapa peringatan portabilitas: psopsi tergantung pada OS! Anda malah bisa menggunakan varian dari: { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1. attidak dapat tersedia (aneh, tetapi ini terjadi ...). $(...)membutuhkan shell yang tidak reallllly lama, jika tidak gunakan backticks.

Olivier Dulac
sumber
Ini tampaknya berbahaya, memahami pid dapat melakukan hal-hal yang tidak terduga jika lebih dari satu proses berjalan dengan nama yang sama, atau bahkan, jika proses lain berisi kata openocd.
orion
1
@orion: saya memberikan contoh sederhana untuk memberikan ide, kekhawatiran yang Anda sebutkan mudah untuk dihilangkan: telah atmemulai skrip yang meluncurkan program dan memberikan pidnya sebagai gantinya dalam file, dan minta skrip utama menunggu untuk itu File muncul dan kemudian membaca pid dari itu.
Olivier Dulac
tentu saja Anda harus mengganti di grep saya (terlalu sederhana) contoh grep dengan tes di dalam awk, di kolom kanan ($ 8, biasanya) (kolom tergantung pada os Anda dan versi / opsi ps)
Olivier Dulac