วิธีเพิ่ม daemon ที่กำหนดเองลงใน init.d อย่างถูกต้อง


26

ฉันมี daemon เซิร์ฟเวอร์แอปพลิเคชันที่เป็นกรรมสิทธิ์ของบุคคลที่ 3 ซึ่งสามารถเริ่มต้นและหยุดได้โดยบรรทัดคำสั่งสองสามตัว ฉันต้องการภูตนี้เพื่อเริ่มต้นเมื่อระบบเริ่มต้นขึ้นและหยุดอย่างถูกต้องเมื่อระบบปิดเครื่อง ฉันจะใช้สิ่งนี้อย่างถูกต้องได้อย่างไร มันเพียงพอที่จะคัดลอกสคริปต์ภายใน / etc / in.d.d และแก้ไขตาม?

คำตอบ:


16

init.d เป็นระบบเก่าที่เลิกใช้แล้วสำหรับการเริ่มดีมอน จะได้รับการแทนที่ด้วยพุ่งพรวด พุ่งพรวดมีข้อได้เปรียบของความง่ายในการกำหนดค่าและอนุญาตให้เรียงลำดับที่เหมาะสมของการเริ่มต้นงาน

ไฟล์คอนฟิกูเรชันสำหรับ upstart live in / etc / init และถ้า daemon ของคุณไม่มีสิ่งที่จำเป็นต้องมีก่อนสิ่งนั้นสามารถทำได้ง่ายเหมือน tty1.conf:

# tty1 - getty
#
# This service maintains a getty on tty1 from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -8 38400 tty1

ในกรณีนี้คุณสามารถคัดลอกไฟล์นั้นและแก้ไขเพื่อลิ้มรส การกำหนดค่าที่ซับซ้อนมากขึ้นนั้นได้รับการจัดทำเป็นเอกสารที่ดีที่สุดในไซต์ที่ไม่ธรรมดาและในรายการอื่น ๆ ใน / etc / init

เพิ่มในการตอบกลับความคิดเห็น

ไม่ว่าคุณจะใช้พุ่งพรวดหรือ init.d คุณยังคงต้องการวิธีในการพิจารณาว่า Firebird เริ่มต้นได้อย่างถูกต้องเมื่อใด น่าเสียดายที่ Firebird นั้นดูเหมือนจะไม่มีวิธีที่ดีในการตรวจสอบว่ามีการติดตั้งและใช้งานอยู่ ดังนั้นคำแนะนำในการติดโปรแกรมของคุณเริ่มต้นใน /etc/rc.local แน่นอนว่าง่ายที่สุดและบน Ubuntu - อย่างน้อย - รับประกันว่าจะทำงานได้ช้าที่สุดในกระบวนการบู๊ต


1
ที่จริงภูตของฉันขึ้นอยู่กับเซิร์ฟเวอร์ฐานข้อมูล Firebird ซึ่งใช้ init.d
Ivan

12

หากคุณไม่ต้องการโยกย้ายไปยัง UPSTART แต่ต้องการวิธีการแบบคลาสสิกคุณต้อง:

หมายเหตุ: ฉันกำลังบันทึกบริการและโปรแกรมที่มีชื่อเดียวกันในไดเรกทอรีต่าง ๆ (แต่คุณสามารถเปลี่ยนแปลงได้ตราบใดที่มันยังปรากฏอยู่ในแฟ้มบริการของคุณ) เปลี่ยน "myscriptname" และ "myprogramname" เป็นชื่อจริง!

  1. บันทึกโปรแกรมของคุณที่จะทำงานเป็นบริการใน / usr / sbin

    sudo cp myprogramname /usr/sbin/myscriptname

  2. สร้างสคริปต์เริ่มต้นพื้นฐาน (ใช้ /etc/init.d/skeleton เป็นข้อมูลอ้างอิง)

  3. ย้ายสคริปต์นี้ไปที่ /etc/init.d

    sudo mv /etc/init.d/myscriptname

  4. ให้สิทธิ์การใช้งานสคริปต์นี้ (ฉันใช้ 775 แต่คุณสามารถตั้งค่าได้ต่ำกว่า)

    sudo chmod 755 /etc/init.d/myscriptname

  5. goto /etc/init.d

    cd /etc/init.d

  6. รวมในรายการเริ่มต้นที่มีลำดับความสำคัญเริ่มต้นต่ำ

    sudo update-rc.d myscriptname defaults 97 03

รีบูตเครื่องของคุณและตรวจสอบว่าบริการได้เริ่มอย่างถูกต้อง

sudo ps -A --sort cmd

หากบริการของคุณไม่เริ่มต้นอย่างถูกต้องคุณควรตรวจสอบก่อนว่าบริการนั้นทำงานเมื่อมีการเรียกด้วยมือ:

cd /etc/init.d
sudo service myscriptname start

ด้านล่างฉันมีไฟล์บริการตัวอย่างที่ใช้งานได้จริง เปรียบเทียบกับบริการโครงกระดูกเพื่อที่จะเข้าใจสิ่งที่คุณต้องการกำหนดค่า หมายเหตุ: ใช้งานได้กับ Ubuntu 12.04 amazon cloud AWS EC2 การใช้งาน LAMP แบบคลาสสิก (บน Kubuntu 15.10)

#! /bin/sh
### BEGIN INIT INFO
# Provides:          
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Sample_GT02 daemon startup script
# Description:       Sample Server for GT02 class 
### END INIT INFO

# Author: Tony Gil 
#

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Sample Daemon"
NAME=sampleserver_gt02
DAEMON=/usr/sbin/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
CHUID=root

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
   # Return
   #   0 if daemon has been started
   #   1 if daemon was already running
   #   2 if daemon could not be started
   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
      || return 1
   start-stop-daemon --start --quiet --chuid $CHUID --pidfile $PIDFILE --exec $DAEMON -- \
      $DAEMON_ARGS \
      || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
   # Return
   #   0 if daemon has been stopped
   #   1 if daemon was already stopped
   #   2 if daemon could not be stopped
   #   other if a failure occurred
   start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
   RETVAL="$?"
   [ "$RETVAL" = 2 ] && return 2
   # Wait for children to finish too if this is a daemon that forks
   # and if the daemon is only ever run from this initscript.
   # If the above conditions are not satisfied then add some other code
   # that waits for the process to drop all resources that could be
   # needed by services started subsequently.  A last resort is to
   # sleep for some time.
   start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
   [ "$?" = 2 ] && return 2
   # Many daemons don't delete their pidfiles when they exit.
   rm -f $PIDFILE
   return "$RETVAL"
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
   #
   # If the daemon can reload its configuration without
   # restarting (for example, when it is sent a SIGHUP),
   # then implement that here.
   #
   start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
   return 0
}

case "$1" in
  start)
   [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
   do_start
   case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
   esac
   ;;
  stop)
   [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
   do_stop
   case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
   esac
   ;;
  #reload|force-reload)
   #
   # If do_reload() is not implemented then leave this commented out
   # and leave 'force-reload' as an alias for 'restart'.
   #
   #log_daemon_msg "Reloading $DESC" "$NAME"
   #do_reload
   #log_end_msg $?
   #;;
  restart|force-reload)
   #
   # If the "reload" option is implemented then remove the
   # 'force-reload' alias
   #
   log_daemon_msg "Restarting $DESC" "$NAME"
   do_stop
   case "$?" in
     0|1)
      do_start
      case "$?" in
         0) log_end_msg 0 ;;
         1) log_end_msg 1 ;; # Old process is still running
         *) log_end_msg 1 ;; # Failed to start
      esac
      ;;
     *)
        # Failed to stop
      log_end_msg 1
      ;;
   esac
   ;;
  *)
   #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
   echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
   exit 3
   ;;
esac

:

1
@ JakeGould คุณต้องใช้เวลาในการฟอร์แมตโค้ด "my" อีกครั้ง หมายความว่าคุณทดสอบและมันใช้ได้กับคุณ
tony gil

1
มันใช้งานได้สำหรับฉัน
Mario S

ไม่พุ่งพรวดตายตอนนี้ชอบ systemd?
Gillespie

อันที่จริงแล้วคนธรรมดาไม่ได้ติดตั้งบน Ubuntu ล่าสุดของฉัน สคริปต์ init ของ SysV จะไม่มีวันตาย
Chris Nadovich

8

ทำสำเนา /etc/init.d/skeleton และแก้ไขในสถานที่ที่เหมาะสมเพื่อเริ่ม / หยุด / เริ่มบริการของคุณใหม่ มีการแสดงความคิดเห็นเป็นอย่างดีดังนั้นคุณควรสร้างสคริปต์ init.d ที่ใช้งานได้ในเวลาไม่นาน


หมายความว่าคุณต้องการสร้างลิงก์สัญลักษณ์ใน rcX.d ด้วย อย่างไรก็ตามการอัปเดต Ubuntu จะล้างลิงก์สัญลักษณ์ที่กำหนดเองทั้งหมดของคุณ
Robin Hsu

2
  • เพิ่มคำสั่งของคุณไปที่ /etc/rc.local
  • เพื่อให้ภูตของคุณเริ่มต้นโดยอัตโนมัติเมื่อระบบเริ่มต้น

1

pleaserunเป็นสคริปต์ทับทิมที่พยายามแก้ไขปัญหาการสร้างสคริปต์เริ่มต้นโดยอัตโนมัติด้วยคำสั่งเดียว อ้างจากหน้ามัน:

"ด้วย pleaserun คุณสามารถสร้างโปรแกรมเรียกใช้ / สคริปต์ / สิ่งต่อไปนี้:

launchd
upstart
systemd
runit sysv
init "

นอกจากนี้ยังตรวจพบว่าระบบ init ใดกำลังใช้งานอยู่ซึ่งจะสร้างสคริปต์ตามลำดับ


ไม่แน่ใจว่า pleaserun ทำการบันทึกด้วยหรือไม่ แต่อีกอันนี้มีการบันทึกด้วย: gist.github.com/naholyr/4275302
Costin Gușă
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.