Introduction: Write a New Service for Linux (opensuse)

About: I like to explore new things and try out stuff. At the moment I'm in to electronics, BLE and LEDs.

This instructable shows you how to write and implement a new service in Linux (opensuse).

You will learn how to turn a shell script into a service.

What is that good for?
With a service you can do various things.
This is to keep track of how many hours I have been online, how many bytes I have downloaded and what my IP was at a special day.

Step 1: What Do I Want the PC Do?

I want to have the following information in a logfile:
- the time of boot.
- Information about the IP, transfered bytes and maybe other stuff before shutdown. Mainly the output of the cmd: "ifconfig"
- the time of shutdown

So I'm going to write a service that does: 
- Writes a timestamp in a file at startup.
- Write me the output of "ifconfig" and a timestamp before shutdown.

Step 2: Make the Shell Script to Test Your Service

Before we really implement a new service we try the commands in a script first.
So open up an editor and insert the following lines:

#! /bin/sh
# This line is a comment

# the next line defines the logfile

# write "Start" and the current date and time to the logfile
echo "Start: " + `date` >>$LOGFILE

# Write the output of ifconfig to the logfile
echo `ifconfig` >>$LOGFILE

# write "Stop" and the current date and time to the logfile
echo "Stop: " + `date` >>$LOGFILE

Save the file as for instance.
Then type
chmod +x
in the console at the directory where the new file is to make you script executable.

First we define a local variable LOGFILE with the name and the complete path to the logfile, with $LOGFILE we can use this variable in this shell script.
The "echo" command does what it says, it echos what is written behind it. Because I wanted a white space after Start: I had to use quotes around "Start: ". The single quotes around `date` tell echo to invoke the command date instead of writing it straight into the file. And the two greater than signs tell echo to append the output to the file instead of writing it to the console.
That's it!

Now type ./ to execute the script and see if the output in the file was written.

It should be something like:

Start:  + Wed Feb 5 16:30:38 CET 2014
enp2s1 Link encap:Ethernet HWaddr ...
Stop:  + Wed Feb 5 16:31:46 CET 2014

Step 3: Introduction to Service-scripts

Every linux distribution has it's own system of start-Scripts.
So the following is exact true for opensuse 13.1. But the principles are the similar with all Linux-distributions.

So let's start:
In opensuse every boot-script is located in the folder /etc/init.d/
So this is where we have to save our script. But the start-scripts are not simple bash-scripts. They have to have a certain format for the automatic boot-process.
The main principle is:
  • All scripts are located in the /etc/init.d/ folder.
  • In this folder are some more folders called rc.0d, rc.1d and up to rc.6d. In these folders are only symbolic links to those scripts that should be executed when the according runlevel is entered or left. For more information about runlevel aks google!
  • So every script has to provide at least to functions: Start and stop.
  • when changing a runlevel, the init-process calls all K-scripts of the old runlevel with the parameter stop and
  • when these are finished, the init-process calls all S-scripts of the new runlevel with the parameter start.
  • The symbolic links have numbers in their name after K or S, and this determines the sequence in which the scripts are called.
But these links are not done by hand, they are generated by a function called insserv. Or you configure the different runlevels with YAST.

Step 4: Write the Service-script

Now we are starting with the script itself. 
In some distributions there are skeletons which you can use for this purpose. You just take them and fill in the stuff you need.
With opensuse there comes nothing like that, so we have to use an existing one and modify it.

Because we are working in /etc/init.d/ you have to be root to edit and save files here.
type: "su" and the root-password to become root.

Just make a new script called networklog and fill it with this content:

#! /bin/sh
# Copyright (c) 2014 andyk75
# Author: andyk75 (instructables)
# /etc/init.d/networklog
#   and symbolic its link
# Provides: networklog
# Required-Start:
# Required-Stop:
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: Start the networklogging
# Short-Description: make Networklog


case "$1" in
echo "Start: " + `date` >>$LOGFILE
echo -n "Starting Networklogging"

## Start daemon with startproc(8). If this fails
## the echo return value is set appropriate.
echo "Stop: " + `date` >>$LOGFILE
echo `ifconfig` >>$LOGFILE
echo -n "Shutting down Networklogging"
## Stop daemon with killproc(8) and if this fails
## set echo the echo return value.
 ## Stop the service and regardless of whether it was
 ## running or not, start it again.
 # Remember status and be quiet
echo -n "Checking for Networkloggingservice "
## Check status with checkproc(8), if process is running
## checkproc will return with exit status 0.
echo "Usage: $0 {start|stop|status|restart|}"
exit 1

And don't forget to make it executable with 'chmod +x networklog'

  1. In the header-Part with "### BEGIN INIT INFO" until "### END INIT INFO" we specify in which runlevels this service should be started (3 + 5) and in which it should be stopped ( 0, 1, 2, 6). And we have a short description of the service. The Required-Start and stop fields are empty, because we do not rely on any other service to be started.
  2. Now again we have a variable called LOGFILE, as in the testscript before.
  3. But the case-instruction is new. When the script is called with a parameter, this parameter can be accessed inside the script with $1, and this is what happens here: According to the parameter the case-statement only executes the lines after the parameter. We have "start", "stop", "restart", "status" and the wildcard "*" which applies if the parameter is something else. You can see at the wildcard's echo, you get the name of the script ($0) itself with a small instruction of how to use it.
  4. Restart doesn't really do anything.
  5. When the init-process calls 'networklog start': the current date with a Start-label is written to the Logfile.
  6. When the init-process calls 'networklog stop': The output of ifconfig and the current date with a stop-label is written to the logfile.
And that's it.

Step 5: Install the Service With Insserv

Now that we have the script-file.
Open a console and go to /etc/init.d/
Now just execute 'insserv networklog' as root and see that there are so new links in the rc_.d-folders.

Because the system is already running and the service isn't started yet, we start it by hand by calling 'networklog start'.
Otherwise you might get an errormessage when shutting down, because there is no networklog-service to be stopped! :-)

That's it!
Now every time you start your system, the time is beeing recorded in the networklogfile in your home directory. And every time you shut down your system, the complete output of ifconfig and the time is being recorded to.

What to do with this log-file? Well that might be in another instructable.