Introduction

In one of our earlier articles we discussed the sysvinit system startup and service manager in detail. In a subsequent article, we compared sysvinit with other two major alternatives to sysvinit i.e. upstart and systemd. In this article, we will demonstrate how we can create our own init script and use it within the sysvinit service startup system.

 

Anatomy of an init script:
The init scripts reside in the /etc/init.d directory which in fact is a soft link to the /etc/rc.d/init.d directory. An init script is a shell script that has some metadata information which is meant to be used by sysvinit followed by the code to manage a service/task/process. As you will see in the sample init script we’ve written and you may also take a look at other init scripts in the /etc/init.d directory, the general structure of the scripts is quite similar.
The script will begin with some metadata information. This will be followed by a couple of functions which will contain code for actions to be performed.
The functions and the code within them is essentially used to start or stop the service or to check it’s status.
After the function definitions have been completed, there would be a case statement.
The expression used with the case statement will be the argument specified to the service script.
The case statement will contain cases corresponding to the functions that were defined earlier in the script.

Given below is a sample init script I’ve written named myservice.

#!/bin/sh 
# 
# Demonstrate creating your own init scripts 
# chkconfig: 2345 91 64 
### BEGIN INIT INFO 
# Provides: Welcome 
# Required-Start: $local_fs $all 
# Required-Stop: 
# Default-Start: 2345 
# Default-Stop: 
# Short-Description: Display a welcome message 
# Description: Just display a message. Not much else. 
###END INIT INFO 

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

broken_lock_file_for_centos=/var/lock/subsys/myservice

start()  { 
   touch "$broken_lock_file_for_centos" 
   echo "Welcome to Linux message by Sahil Suri" 
   sleep 2
 } 

case "$1" in  
      start) 
       start
        ;; 

      stop)
       rm -f  "$broken_lock_file_for_centos" 
       echo "System is shutting down"  
       sleep 2 
        ;; 

     status) 
       echo "Everything looks good"
        ;; 

         *)
       echo $"Usage: $0 {start|stop|status}" 
       exit 5 
esac 
exit $?

 

Explanation:

  • The commented information in the beginning of the script is the metadata information to be used by sysvinit.
    The chkconfig directive defines at which run levels the service should be enabled and also specifies the numbered prefixes to use while creating the links for start-up and kill scripts.
  • In the Required-Start, we define what service should already be available before this service can be started. $local_fs and $all imply that all local file systems should be mounted and this service should be started towards the end of the boot process.
  • The Default-Start defines the run levels at which the service should be available.
  • The Required-Stop directive implies the service in consideration for which this script is written should stop before the boot facilities or services mentioned in this directive.
  • The Default-Stop directive implies the run levels at which the script should be stopped.
  • Once this metadata section has been appropriately populated, we come to the actual code that defines the service behavior. Within the body of the script, we define a function named start containing a simple echo statement.
  • Then we’ve written a case statement using the first argument written with the script as the expression for the case statement. We’ve written a couple of cases in the case statement corresponding to common actions we associate with an init script.

 

Note: Notice that we are creating a lock file named /var/lock/subsys/myservice. The reason I’m mentioning this separately is because this inclusion is of major significance. If you do not include the creation and removal of a lock file then during system boot and shutdown, init will start the service during the boot phase but will ignore the stop part of the script during the shutdown phase.

 

Demonstration:
Now that our script is ready, let’s test it out.

First, let’s ensure that the script has execute permissions set.

[root@linuxnix init.d]# ls -l myservice
-rw-r--r--. 1 root root 730 Feb 3 13:09 myservice
[root@linuxnix init.d]# chmod +x myservice

Now let’s run the script.

[root@linuxnix init.d]# ./myservice status
Everything looks good
[root@linuxnix init.d]# ./myservice
Usage: ./myservice {start|stop|status}
[root@linuxnix init.d]#

The script appears to be running as expected. Now let’s test this using the service command.

[root@linuxnix init.d]# service myservice status
Everything looks good
[root@linuxnix init.d]#
[root@linuxnix init.d]# service myservice start
Welcome to Linux message by Sahil Suri
[root@linuxnix init.d]#

Thus far we’ve created our init script and tested that it’s working. Now let’s enable it on boot using the chkconfig command.

[root@linuxnix init.d]# chkconfig myservice on
 [root@linuxnix init.d]#

With that done, we’ll now verify that the soft link names have been set according to the numbers we defined in the chkconfig directive in the init script.

[root@linuxnix rc3.d]# pwd
/etc/rc3.d
[root@linuxnix rc3.d]# ls -l S91myservice
lrwxrwxrwx. 1 root root 19 Feb 3 13:31 S91myservice -> ../init.d/myservice
[root@linuxnix rc3.d]#
[root@linuxnix rc1.d]# pwd
/etc/rc1.d
[root@linuxnix rc1.d]# ls -l K64myservice
lrwxrwxrwx. 1 root root 19 Feb 3 13:31 K64myservice -> ../init.d/myservice
[root@linuxnix rc1.d]#

 

Conclusion

In this article, we did a breakdown of how init scripts present in the /etc/init.d directory are structured and gained an understanding of their functionality by writing a quick init script of our own. We hope that the explanation provided in this article helps you better comprehend existing init scripts on your system and write more complex init scripts suiting your requirements.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.