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.
Sahil Suri
Latest posts by Sahil Suri (see all)
- Google Cloud basics: Activate Cloud Shell - May 19, 2021
- Create persistent swap partition on Azure Linux VM - May 18, 2021
- DNF, YUM and RPM package manager comparison - May 17, 2021
- Introduction to the aptitude package manager for Ubuntu - March 26, 2021
- zypper package management tool examples for managing packages on SUSE Linux - March 26, 2021