Kabuk betiğini arka plan programı olarak çalıştırmanın “uygun” yolu


20

Başlangıçta daemontools veya daemonize gibi harici araçlar kullanmadan bir daemon olarak çalıştırmak istediğim bir kabuk komut dosyası yazıyorum .


Linux Daemon Yazma NASIL

Göre Linux Daemon Yazma NASIL , bir düzgün cini aşağıdaki özelliklere sahiptir:

  • Üst işlemden çatallar
  • kapanır tüm dosya tanımlayıcıları (yani stdin, stdout, stderr)
  • yazma için günlükleri açar (yapılandırılmışsa)
  • değişikliği çalışma dizini (genellikle kalıcıdır birine /)
  • dosya modu maskesini sıfırlar (umask)
  • benzersiz bir Oturum Kimliği (SID) oluşturur

Daemonize Giriş

Artalanda Giriş söylemektedir olması da tipik bir cin:

  • (varsa) kontrol terminalinden ayrılır ve tüm terminal sinyallerini yoksayar
  • süreç grubundan ayrılıyor
  • kolları SIGCLD

Nasıl bütün bu yapacağını sh, dashya da bashtek ortak Linux araçları ile komut?

Debian bizim birincil odak noktamız olmasına rağmen, komut dosyası ek yazılım olmadan olabildiğince çok dağıtımda çalışabilmelidir .


NOT: StackExchange ağında nohupveya kullanımını öneren çok sayıda yanıt olduğunu biliyorum setsid, ancak bu yöntemlerin hiçbiri yukarıdaki tüm gereksinimleri ele almaz.


DÜZENLEME: Daemon (7) manpage eski tarzı arasında bazı farklılıklar var gibi görünmektedir rağmen ayrıca, bazı önemli noktaları verir SysVcinleri ve daha yeni systemdolanlar. Çeşitli dağıtımlarla uyumluluk önemli olduğundan, lütfen cevabın herhangi bir farklılığı netleştirdiğinden emin olun.



1
Kendi kabuk senaryo yazmak "doğru" yolu, kendi günlüğünü yetinmek vb cini, olarak başlatılması için bir yöntem temin etmektir gibi şeyler daemonve bu diğer şeyler çalışan içindir keyfi olarak çalıştırmak için hiçbir hükmü kabuk komut dosyalarını bir daemon. Yazar olduğunuzdan, bu komut dosyasının nasıl yazıldığını tamamen kontrol ettiğiniz için, bunu sadece bir systemd unitfile veya rc.d komut dosyasından başlatılabilmesini sağlayın. Sen ki "Doğru" belirtmek!
Zengin

Yanıtlar:


16

Systemd'i kullanarak basit bir birim oluşturarak bir betik'i arka plan programı olarak çalıştırabilmelisiniz. Ekleyebileceğiniz birçok farklı seçenek var, ancak bu alabileceğiniz kadar basit.

Senaryonuz olduğunu varsayalım /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Bir birim oluşturursunuz /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

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

[Install]
WantedBy=multi-user.target 

Şeytanı başlatmak için koştun

systemctl start mydaemon.service 

Önyüklemeye başlamak için etkinleştirin

systemctl enable mydaemon.service

Eğer Linux dağıtımlarının çoğunluğu bugün bir systemd tabanlı bir sistemde, üzerinde, bu gerçekten bir dış araç değildir. Olumsuz olsa da her yerde çalışmaz olurdu.


3
Ben sistemd yaklaşımını severken, OP "hiçbir harici araç" dedi. Henüz systemd bulunmayan Linux dağıtımları vardır veya systemd ile başka bir şey arasında seçim yapmanıza izin verir, örneğin OpenRC.
Cristian Ciupitu

5
Systemd kullanan dağıtımlar systemdiçin artık bir "harici araç" değildir bash.
Alexander

7

Muhtemelen burada bir şey eksik; neden tam nohupolarak uygun olmaz? Tabii ki yeterli değil tek başına değil , ama takviye etmek basit görünüyor.

#!/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 &

Görebildiğim kadarıyla:

  • çıktı uygun şekilde yeniden yönlendirilir (gerekirse / dev / null kullanın)
  • umask miras
  • stdin ancak ana komut dosyasının sonunda ölür
  • daemon.sh betiği init(veya systemd) ile bildirilir

Ben bariz özlüyorum güçlü bir duygu var. Downvote, ama lütfen bana ne olduğunu söyle :-)


2
Çok benzer bir şey önermek üzereydim. Kullandığım nohupile &ve I / O yönlendirmesi birkaç olmayan başlatmak için - CDaemon araçları da sarma belki ek güvenlik nohupbir komut içini su -c "nohup ... &" -s /bin/bash systemUserolmayan bir ayrıcalıklı kullanıcı olarak daemon'nını çalıştırmak.
111 -

4

screenÇoğu dağıtımda bulunan Linux komutu bir kabuk betiğini arka plana alabilir. Sık kullanıyorum. Ayrılmış bir ekran oturumunu başlatmak, listelemek ve çıkmak için hızlı bir örnek ...

# 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

2
screenkabuk betiğini deamonize etmez. Sadece seçkin terminalde çalıştırırlar ve oturumu kapatmadan bu terminalden (klavyeyi PC'den çıkar gibi) çıkarabilirler. Yani, ayrılmış terminalde çalışan program arka planda çalışıyor. Bu nedenle - geçiş programını arka planda ayırın.
Yurij Goncharuk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.