125

I think I read something a while back about this, but I can't remember how it's done. Essentially, I have a service in /etc/init.d which I'd like to start automatically at boot time. I remember it has something to do with symlinking the script into the /etc/rc.d directory, but I can't remember at the present. What is the command for this?

I believe I'm on a Fedora/CentOS derivative.

jasonwryan
  • 73,126
Naftuli Kay
  • 39,676
  • That depends on your OS. What unix variant are you running, and if Linux, what distribution? Which amongst /etc/init, /etc/init.d, /etc/rc.d, /etc/rc.local and a few more does it have? – Gilles 'SO- stop being evil' Sep 08 '11 at 23:40
  • 1
    I think I'm on CentOS or something like it. Would the answer differ for Debian? I'm interested in a solution for Debian too. – Naftuli Kay Sep 08 '11 at 23:43

4 Answers4

146

If you are on a Red Hat based system, as you mentioned, you can do the following:

  1. Create a script and place in /etc/init.d (e.g /etc/init.d/myscript). The script should have the following format:
#!/bin/bash
# chkconfig: 2345 20 80
# description: Description comes here....

# Source function library.
. /etc/init.d/functions

start() {
    # code to start app comes here 
    # example: daemon program_name &
}

stop() {
    # code to stop app comes here 
    # example: killproc program_name
}

case "$1" in 
    start)
       start
       ;;
    stop)
       stop
       ;;
    restart)
       stop
       start
       ;;
    status)
       # code to check status of app comes here 
       # example: status program_name
       ;;
    *)
       echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

The format is pretty standard and you can view existing scripts in /etc/init.d. You can then use the script like so /etc/init.d/myscript start or chkconfig myscript start. The ckconfig man page explains the header of the script:

 > This says that the script should be started in levels 2,  3,  4, and
 > 5, that its start priority should be 20, and that its stop priority
 > should be 80.

The example start, stop and status code uses helper functions defined in /etc/init.d/functions

  1. Enable the script

    $ chkconfig --add myscript 
    $ chkconfig --level 2345 myscript on 
    
  2. Check the script is indeed enabled - you should see "on" for the levels you selected.

    $ chkconfig --list | grep myscript
    
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
canen
  • 1,671
  • 4
    Chkconfig is what u want. +1 – whoami Sep 09 '11 at 08:31
  • Why have init start something at runlevels 2, 3, 4 and 5? Don't you have to take care to avoid starting a server at runlevel 2? And runlevel 4 isn't defined on RHEL anyway, so why try to start it at that runlevel? Not criticism, just wanting to know. I'm a native Slackware user. –  Sep 09 '11 at 13:35
  • 4 isn't defined on RHEL, but it does exist. You can steal it for your own things. – Kevin M Sep 09 '11 at 16:25
  • The header is taken from the chkconfig man page. I personally stick with 235 or just 35 in most cases. – canen Sep 10 '11 at 06:33
  • Is there a log I can look at if something fails to start during startup? – Utkarsh Sinha May 29 '14 at 13:17
  • for a CUI based interface you can use ntsysv to configure the runlevels – Jasen Apr 12 '16 at 20:48
  • Unfortunately this didn't work on Raspberry Pi running Raspbian Jessie. I still have to login if I want my Ngrok script to execute... – IgorGanapolsky Aug 07 '16 at 22:16
  • Is there a particular reason why the script should exit with a code at the end? – Arj Aug 17 '16 at 17:06
  • Instead of chkconfig myscript start we can use service myscript start, right? – masterxilo Jun 01 '18 at 13:28
  • How does /etc/init.d/myscript start work to start your program? Oh....I get it. The switch case parses arg 1 ($1), and if it is the string "start", it calls the start function. – Gabriel Staples Feb 15 '23 at 17:52
20

You test, what runlevel your machine normally starts into.

runlevel

Often this is 5 or 2 - there are various conventions, but nothing really established, afaik. Ubuntu uses 2, while former distribution I used always used

  • 1 Single user (super user)
  • 2 multi user
  • 3 multi user + network
  • 4 not used / user definable
  • 5 multi user, network + X11

Then you make a symlink from your init-script, maybe /etc/init.d/foobar to /etc/rc2.d/SXYfoobar

S means 'Start this script in this runlevel (here: 2). XY is a two-digit decimal number, which is relevant for the sequence, the scripts are started.

If you depend on script S45barfoo to be run before you, and S55foofoo is depending on your script, you would choose xy between 45 and 55. For equal numbers the boot order is undefined.

Ubuntu meanwhile switched (is switching) to another startup procedure, called upstart.

And note: Not always the links link to /etc/rcX.d - sometimes it is /etc/init/rcX.d or something similar, but it should be easy to find, somewhere below /etc.

If you want to start something at the end of the starting scripts, /etc/rc.local would be file to look for, but if it depends on X11 already running, you might look for an autostart-option of your desktop environment, or /etc/X11/Xsession.d/ with a similar pattern as described above.

If you depend on the network being up, there is a separate directory (if-up.d), and for mounted devices like external USB-drives /etc/udev/rules.d/.

user unknown
  • 10,482
5

In this answer, let's assume I want to mount Windows Shares (CIFS) defined in /etc/fstab via mount -a -t cifs via a service script on an Ubuntu system. First, I create an entry under /etc/init.d/mountcifs with the content:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          mountcifs
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Mounts / Umounts Window Shares (CIFS)
# Description: Mounts / Umounts Window Shares (CIFS)
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/lsb/init-functions

case "$1" in start) mount -a -t cifs ;; stop) umount -a -t cifs ;; restart|reload|force-reload) umount -a -t cifs mount -a -t cifs ;; *) # echo "Usage: $0 start|stop" >&2 # exit 3 ;; esac

Ensure that /etc/init.d/mountcifs is executable with chmod 755 /etc/init.d/mountcifs.

Note the # Default-Start: 2 3 4 5 in the comments. Because of this comment, we can get Ubuntu to create the symbolic links in the /etc/rc2.d, /etc/rc3.d, /etc/rc4.d and /etcrc5.d folders with the following command:

sudo update-rc.d mountcifs defaults

Then we can test the script as follows:

sudo service start mountcifs
df -h # should see Windows Shares
sudo service stop mountcifs
df -h # all Windows Shares should be gone
sudo service start mountcifs
df -h # all Windows Shares should be back

The Windows Shares should be automounted on a reboot.

3

As Naftuli Tzvi Kay asked about Debian above: Beginning with Debian 6, your script should contain a LSB (Linux Standards Base) header which indicates its dependencies and capabilities (see debian wiki page).

If a LSB header is present, you can use insserv to include your script in the boot process (see another debian wiki page).

mdt
  • 41
  • 4