Как написать демон на bash

A Daemon is just program that runs as a background process, rather than being under the direct control of an interactive user…

[The below bash code is for Debian systems — Ubuntu, Linux Mint distros and so on]

The simple way:

The simple way would be to edit your /etc/rc.local file and then just have your script run from there (i.e. everytime you boot up the system):

sudo nano /etc/rc.local

Add the following and save:

#For a BASH script
/bin/sh TheNameOfYourScript.sh > /dev/null &

The better way to do this would be to create a Daemon via Upstart:

sudo nano /etc/init/TheNameOfYourDaemon.conf

add the following:

description "My Daemon Job"
author "Your Name"
start on runlevel [2345]    

pre-start script
  echo "[`date`] My Daemon Starting" >> /var/log/TheNameOfYourDaemonJobLog.log
end script

exec /bin/sh TheNameOfYourScript.sh > /dev/null &

Save this.

Confirm that it looks ok:

init-checkconf /etc/init/TheNameOfYourDaemon.conf

Now reboot the machine:

sudo reboot

Now when you boot up your system, you can see the log file stating that your Daemon is running:

cat  /var/log/TheNameOfYourDaemonJobLog.log

• Now you may start/stop/restart/get the status of your Daemon via:

restart: this will stop, then start a service

sudo service TheNameOfYourDaemonrestart restart

start: this will start a service, if it’s not running

sudo service TheNameOfYourDaemonstart start

stop: this will stop a service, if it’s running

sudo service TheNameOfYourDaemonstop stop

status: this will display the status of a service

sudo service TheNameOfYourDaemonstatus status

#!/bin/sh # This is a skeleton of a bash daemon. To use for yourself, just set the # daemonName variable and then enter in the commands to run in the doCommands # function. Modify the variables just below to fit your preference. daemonName=«DAEMON-NAME« pidDir=«.« pidFile=«$pidDir/$daemonName.pid« pidFile=«$daemonName.pid« logDir=«.« # To use a dated log file. # logFile=»$logDir/$daemonName-«`date +»%Y-%m-%d»`».log» # To use a regular log file. logFile=«$logDir/$daemonName.log« # Log maxsize in KB logMaxSize=1024 # 1mb runInterval=60 # In seconds doCommands() { # This is where you put all the commands for the daemon. echo «Running commands.« } ################################################################################ # Below is the skeleton functionality of the daemon. ################################################################################ myPid=`echo $$` setupDaemon() { # Make sure that the directories work. if [ ! -d «$pidDir« ]; then mkdir «$pidDir« fi if [ ! -d «$logDir« ]; then mkdir «$logDir« fi if [ ! -f «$logFile« ]; then touch «$logFile« else # Check to see if we need to rotate the logs. size=$((`ls l «$logFile» | cut d » » f 8`/1024)) if [[ $size -gt $logMaxSize ]]; then mv $logFile «$logFile.old« touch «$logFile« fi fi } startDaemon() { # Start the daemon. setupDaemon # Make sure the directories are there. if [[ `checkDaemon` = 1 ]]; then echo « * 33[31;5;148mError33[39m: $daemonName is already running.« exit 1 fi echo « * Starting $daemonName with PID: $myPid.« echo «$myPid« > «$pidFile« log *** `date +«%Y-%m-%d«`«: Starting up $daemonName.« # Start the loop. loop } stopDaemon() { # Stop the daemon. if [[ `checkDaemon` -eq 0 ]]; then echo « * 33[31;5;148mError33[39m: $daemonName is not running.« exit 1 fi echo « * Stopping $daemonName« log *** `date +«%Y-%m-%d«`«: $daemonName stopped.« if [[ ! -z `cat $pidFile` ]]; then kill -9 `cat «$pidFile«` &> /dev/null fi } statusDaemon() { # Query and return whether the daemon is running. if [[ `checkDaemon` -eq 1 ]]; then echo « * $daemonName is running.« else echo « * $daemonName isn’t running.« fi exit 0 } restartDaemon() { # Restart the daemon. if [[ `checkDaemon` = 0 ]]; then # Can’t restart it if it isn’t running. echo «$daemonName isn’t running.« exit 1 fi stopDaemon startDaemon } checkDaemon() { # Check to see if the daemon is running. # This is a different function than statusDaemon # so that we can use it other functions. if [ -z «$oldPid« ]; then return 0 elif [[ `ps aux | grep «$oldPid« | grep -v grep` > /dev/null ]]; then if [ -f «$pidFile« ]; then if [[ `cat «$pidFile«` = «$oldPid« ]]; then # Daemon is running. # echo 1 return 1 else # Daemon isn’t running. return 0 fi fi elif [[ `ps aux | grep «$daemonName« | grep -v grep | grep -v «$myPid« | grep -v «0:00.00«` > /dev/null ]]; then # Daemon is running but without the correct PID. Restart it. log *** `date +«%Y-%m-%d«`«: $daemonName running with invalid PID; restarting.« restartDaemon return 1 else # Daemon not running. return 0 fi return 1 } loop() { # This is the loop. now=`date +%s` if [ -z $last ]; then last=`date +%s` fi # Do everything you need the daemon to do. doCommands # Check to see how long we actually need to sleep for. If we want this to run # once a minute and it’s taken more than a minute, then we should just run it # anyway. last=`date +%s` # Set the sleep interval if [[ ! $((nowlast+runInterval+1)) -lt $((runInterval)) ]]; then sleep $((nowlast+runInterval)) fi # Startover loop } log() { # Generic log function. echo «$1« >> «$logFile« } ################################################################################ # Parse the command. ################################################################################ if [ -f «$pidFile« ]; then oldPid=`cat «$pidFile«` fi checkDaemon case «$1« in start) startDaemon ;; stop) stopDaemon ;; status) statusDaemon ;; restart) restartDaemon ;; *) echo «33[31;5;148mError33[39m: usage $0 { start | stop | restart | status }« exit 1 esac exit 0

Reading Time: 3 minutes

Hello readers, in this blog we will be looking at what are daemons and how can we create a custom daemons in our systems. Daemon is called as a type of program which quietly runs in the background rather than under the direct control of a user. It means that a daemon does not interact with the user.

Systemd

Management of daemons is done using systemd. It is a system and service manager for Linux operating systems. It is designed to be backwards compatible with SysV init scripts, and provides a number of features such as parallel startup of system services at boot time, on-demand activation of daemons, or dependency-based service control logic.

Units

Systemd introduced us with the concept of systemd units. These units are represented by unit configuration files located in one of the directories listed below:

Directory Description
/usr/lib/systemd/system/ Systemd unit files distributed with installed RPM packages.
/run/systemd/system/ Systemd unit files created at run time. This directory takes precedence over the directory with installed service unit files.
/etc/systemd/system/ Systemd unit files created by systemctl enable as well as unit files added for extending a service. This directory takes precedence over the directory with runtime unit files.

We have multiple unit types available to us. The below table gives a brief description for each of them.

Unit Type File Extension Description
Service unit .service A system service.
Target unit .target A group of systemd units.
Automount unit .automount A file system automount point.
Device unit .device A device file recognized by the kernel.
Mount unit .mount A file system mount point.
Path unit .path A file or directory in a file system.
Scope unit .scope An externally created process.
Slice unit .slice A group of hierarchically organized units that manage system processes.
Snapshot unit .snapshot A saved state of the systemd manager.
Socket unit .socket An inter-process communication socket.
Swap unit .swap A swap device or a swap file.
Timer unit .timer A systemd timer.

In this blog, we will be looking at Service unit and how to use them to create daemons.

Creating Our Own Daemon

At many times we will want to create our own services for different purposes. For this blog, we will be using a Java application, packaged as a jar file and then we will make it run as a service.

Step 1: JAR File

The first step is to acquire a jar file. We have used a jar file which has implemented a few routes in it.

Step 2: Script

Secondly, we will be creating a bash script that will be running our jar file. Note that there is no problem in using the jar file directly in the unit file, but it is considered a good practice to call it from a script. It is also recommended to store our jar files and bash script in /usr/bin directory even though we can use it from any location on our systems.

#!/bin/bash
/usr/bin/java -jar <name-of-jar-file>.jar

Make sure that you make this script executable before running it: chmod +x <script-name>.sh

Step 3: Units File

Now that we have created an executable script, we will be using it into make our service.

We have here a very basic .service unit file.

[Unit]
Description=A Simple Java Service

[Service]
WorkingDirectory=/usr/bin
ExecStart= /bin/bash /usr/bin/java-app.sh
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

In this file, the Description tag is used to give some detail about our service when someone will want to see the status of the service.
The WorkingDirectory is used to give path of our executables.
ExecStart tag is used to execute the command when we start the service.
The Restart tag configures whether the service shall be restarted when the service process exits, is killed, or a timeout is reached.
multi-user.target normally defines a system state where all network services are started up and the system will accept logins, but a local GUI is not started. This is the typical default system state for server systems, which might be rack-mounted headless systems in a remote server room.

Step 4: Starting Our Daemon Service

Let us now look at the commands which we will use to run our custom daemon.

sudo systemctl daemon-reload
# Uncomment the below line to start your service at the time of system boot
# sudo systemctl enable <name-of-service>.service
sudo systemctl start <name-of-service>
# OR
# sudo service <name-of-service> start
sudo systemctl status <name-of-service>
# OR
# sudo service <name-of-service> status

Conclusion

In this blog, we have looked how to make custom daemons and check their status as well. Also, we observed that it is fairly easy to make these daemons and use them. We hope that everyone is now comfortable enough to make daemons on their own.

References:

https://dzone.com/articles/run-your-java-application-as-a-service-on-ubuntu
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-managing_services_with_systemd

Using systemd you should be able to run a script as a daemon by creating a simple unit.
There are a lot of different options you can add but this is about as simple as you can get.

Say you have a script /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Don’t forget to sudo chmod +x /usr/bin/mydaemon.

You create a unit /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

To start the demon you run

systemctl start mydaemon.service 

To start at boot you enable it

systemctl enable mydaemon.service

If on a systemd based system, which a majority of Linux distributions are today, this isn’t really an external tool. The negative would be that it won’t work everywhere though.

Like this post? Please share to your friends:
  • Как написать делягину михаилу письмо
  • Как написать дельту на клавиатуре
  • Как написать дельта на клавиатуре компьютера
  • Как написать деловой текст
  • Как написать деловой email на английском