如何正确添加自定义守护程序到init.d?

我有一个第三方专有的应用服务器守护进程,可以通过几个命令行启动和停止。 我需要这个守护进程在系统启动时启动并在系统关闭时正确停止。 我该如何正确实现? 是否足以复制/etc/init.d中的一些脚本并相应地修改它?

init.d是用于启动守护进程的旧的,已弃用的系统; 被暴发户取代了。 Upstart的优点是更容易配置,并允许正确排序任务初始化。

upstart的配置文件位于/ etc / init中,如果你的守护进程没有先决条件,它可以像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 

在这种情况下,您可以复制该文件并修改以品味。 更新的配置最好记录在upstart站点和/ etc / init中的其他条目中。

添加以回应评论

无论您使用的是upstart还是init.d,您仍然需要某种方法来确定Firebird何时正确初始化。 不幸的是,Firebird本身似乎没有很好的方法来validation它是否已安装并正在运行 。 因此,将程序开始粘贴到/etc/rc.local的建议肯定是最简单的,并且至少在Ubuntu上保证在启动过程中尽可能晚地运行。

如果您不想迁移到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. 转到/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亚马逊云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 : 

复制/etc/init.d/skeleton并在适当的位置编辑它以启动/停止/重新启动您的服务。 它评论得非常好,因此您应该能够立即创建一个有效的init.d脚本。

  • 将命令添加到/etc/rc.local
  • 这样你的守护进程就会在系统启动时自动启动。

pleaserun是一个ruby脚本,试图解决使用单个命令自动创建init脚本的问题。 从它的页面引用:

“有了pleaserun,你可以生成以下发射器/脚本/其他:

的launchd
暴发户
systemd
运行
sysv init“

它还会检测正在使用的init系统,以便相应地生成脚本。