Cara yang "tepat" untuk menjalankan skrip shell sebagai daemon

20

Saya menulis skrip shell yang ingin saya jalankan sebagai daemon pada startup tanpa menggunakan alat eksternal seperti daemontools atau daemonize .


Linux Daemon Writing HOWTO

Menurut Linux Daemon Writing HOWTO , daemon yang tepat memiliki karakteristik sebagai berikut:

  • garpu dari proses induk
  • menutup semua file deskriptor (yaitu, stdin, stdout, stderr)
  • membuka log untuk penulisan (jika dikonfigurasi)
  • mengubah direktori kerja menjadi yang persisten (biasanya /)
  • mengatur ulang mode file mask (umask)
  • membuat ID Sesi unik (SID)

daemonize Pendahuluan

The daemonize Pendahuluan berjalan lebih jauh, yang menyatakan bahwa daemon khas juga:

  • terlepas dari terminal kontrolnya (jika ada) dan mengabaikan semua sinyal terminal
  • terlepas dari kelompok prosesnya
  • menangani SIGCLD

Bagaimana saya melakukan semua ini dalam sh, dashatau bashnaskah dengan alat Linux umum saja?

Skrip harus dapat dijalankan pada sebanyak mungkin distro tanpa perangkat lunak tambahan, meskipun Debian adalah fokus utama kami.


CATATAN: Saya tahu ada banyak jawaban di jaringan StackExchange yang merekomendasikan penggunaan nohupatau setsid, tetapi tidak satu pun dari metode ini yang menangani semua persyaratan di atas.


EDIT: Halaman daemon (7) juga memberikan beberapa petunjuk, meskipun tampaknya ada beberapa perbedaan antara SysVdaemon gaya lama dan yang lebih baru systemd. Karena kompatibilitas dengan berbagai distro penting, harap pastikan jawabannya memperjelas perbedaan.


pengguna339676
sumber
1
Cara "tepat" untuk membuat skrip shell Anda sendiri adalah dengan membuatnya melakukan pencatatan sendiri, menyediakan metode untuk meluncurkannya sebagai daemon, dll. Hal-hal seperti daemondan hal-hal lain untuk menjalankan skrip shell sewenang-wenang tanpa ketentuan untuk menjalankan sebagai sebuah daemon. Karena Anda penulis, sepenuhnya mengendalikan bagaimana skrip itu ditulis, buatlah sehingga skrip tersebut dapat diluncurkan dari systemd unitfile atau skrip rc.d. Anda tidak menentukan "Proper"!
Kaya

Jawaban:

16

Menggunakan systemd Anda harus dapat menjalankan skrip sebagai daemon dengan membuat unit sederhana. Ada banyak opsi berbeda yang bisa Anda tambahkan tetapi ini sesederhana mungkin.

Katakanlah Anda memiliki skrip /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Anda membuat unit /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

Untuk memulai iblis yang Anda jalankan

systemctl start mydaemon.service 

Untuk memulai saat boot Anda mengaktifkannya

systemctl enable mydaemon.service

Jika pada sistem berbasis systemd, yang mayoritas distro Linux ada saat ini, ini sebenarnya bukan alat eksternal. Yang negatif adalah bahwa itu tidak akan bekerja di mana pun.

johnramsden
sumber
3
Sementara saya suka pendekatan systemd, OP mengatakan "tidak ada alat eksternal". Ada distribusi Linux yang belum memiliki systemd, atau membiarkan Anda menggunakan memilih antara systemd dan sesuatu yang lain, misalnya OpenRC.
Cristian Ciupitu
5
Untuk distro yang menggunakan systemd, systemdtidak lebih dari "alat eksternal" daripada bash.
Alexander
7

Saya mungkin kehilangan sesuatu di sini; mengapa tepatnya tidak nohuptepat? Tentu saja itu tidak cukup sendiri , tetapi menambahkannya langsung saja.

#!/bin/bash

if [ "$1" = "DAEMON" ]; then
    # is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
    trap '' INT
    cd /tmp
    shift
    ### daemonized section ######
    for i in $( seq 1 10 ); do
        date
        sleep 5
    done
    #### end of daemonized section ####
    exit 0
fi

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
umask 022
# You can add nice and ionice before nohup but they might not be installed
nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &

Sejauh yang saya bisa lihat:

  • output diarahkan secara tepat (gunakan / dev / null jika perlu)
  • umask diwarisi
  • stdin mati di akhir skrip induk
  • skrip daemon.sh direparasi ke init(atau systemd)

Aku punya perasaan kuat aku kehilangan yang jelas. Downvote, tapi tolong beri tahu saya apa itu :-)

LSerni
sumber
2
Saya akan menyarankan sesuatu yang sangat mirip. Saya menggunakan nohupdengan &dan pengalihan I / O untuk meluncurkan beberapa Cutilitas non- daemon dengan keamanan tambahan yang membungkus nohupperintah Anda di dalam a su -c "nohup ... &" -s /bin/bash systemUseruntuk menjalankan daemon sebagai pengguna yang tidak memiliki hak istimewa.
111 ---
4

screenPerintah Linux yang terdapat di sebagian besar distro dapat mengubah bentuk skrip shell. Saya sering menggunakannya. Berikut adalah contoh cepat untuk memulai, daftar, dan keluar dari sesi layar terpisah ...

# screen -dmS Session_Name  bash -c "while true; do date; sleep 60; done"

# screen -ls
There are screens on:
        8534.Session_Name       (04/04/2018 08:46:27 PM)        (Detached)

# screen -S Session_Name -X quit
S.Haran
sumber
2
screentidak menghapuskan skrip shell. Itu hanya menjalankan mereka di terminal dibedakan dan dapat melepaskan dari terminal ini (seperti mencabut keyboard dari PC) tanpa sesi penutupan. Jadi, program yang berjalan di terminal terpisah berjalan di latar belakang. Oleh karena itu - lepaskan program lulus di latar belakang.
Yurij Goncharuk