What is start-stop-daemon in linux scripting?
It is a program to manage the start and stop of system level background processes (daemons). You use it by passing in parameters (such as the pid file to create/check) and command arguments for the process you want to launch.
Then, you do one of two things:
start-stop-daemon -S [other arguments] something
start something
, if something
wasn't already running. If it was running, do nothing.
start-stop-daemon -K [other arguments] something
stop something
. If something
wasn't running, do nothing.
The man page provides more information on the various arguments. Typically a template is provided in /etc/init.d/
which has other commands for the init process that controls the running of background processes.
What does it mean?
start-stop-daemon --start --background -m --oknodo
--pidfile ${PIDFILE} --exec ${DAEMON} -- ${TARGETDIR}
--background
= launch as a background process-m
= make a PID file. This is used when your process doesn't create its own PID file, and is used with--background
--oknodo
= return0
, not1
if no actions are taken by the daemon--pidfile ${PIDFILE}
= check whether the PID file has been created or not--exec
= make sure the processes are instances of this executable (in your case,DAEMON
)
start-stop-daemon with --background vs running using & option
If you use start-stop-daemon --background
then start-stop-daemon will fork off a process to run in the background and then start-stop-daemon immediately exits. Among other things this means you can check the exit status of start-stop-daemon.
If you use start-stop-daemon &
then the shell forks off a background process and runs start-stop-daemon in it. You won't be able to check its exit status as it won't actually exit (until the thing it runs exits).
In most cases start-stop-daemon --background
is a better choice.
What is the proper way to terminate a script using start-stop-daemon?
The issue was with the --exec that I used for matching the process name. As per the start-stop-daemon documentation :
-x, --exec executable
Check for processes that are instances of this executable
(according to /proc/pid/exe).
In my case as my script is Perl script, /proc/pid/exe is symlinked to /usr/bin/perl; therefore the exec couldnt match the process name. I removed the exec so that it matches only the PID. Now I can properly stop my process.
start-stop-daemon run with external script condition
Inside the /etc/init.d directory is the file with the service we want to modify, for example the emqx service. We will have something like this:
do_start()
{
start-stop-daemon --start \
--name emqx \
--user emqx \
--exec /usr/local/bin/checkconditionandrun.sh emqx -- start \
|| return 2
}
case "$1" in
start)
log_daemon_msg "Starting emqx"
do_start
case "$?" in
0|1) log_end_msg 0 ;;
2) log_end_msg 1
exit 1
;;
esac
;;
stop)
log_daemon_msg "Stopping emqx"
do_stop
case "$?" in
0|1) log_end_msg 0 ;;
2) log_end_msg 1
exit 1
;;
esac
;;
The key to all this is in two things:
In the do_start() function, the start-stop-daemon --start command should not directly call the "emqx start" command. A script must be called to verify what we need to verify and then that script will or will not execute the command passed as parameter.
Now if we want our service to restart automatically if it has failed, as would be done through a .service with the inputs Restart=always and RestartSec=10, we must know the following:
a) systemd supports legacy scripts /etc/init.d this way, when systemd loads service definitions, systemd-sysv-generator autogenerates .service files on the fly from the scripts in /etc/init.d.
b) We can add configuration to an auto-generated service by adding "drop-in" files called "restart.conf" to a folder with the following name: /etc/systemd/system/servicename.service.d/
As explained above and assuming that our service is called "emqx", we can create a file in the following folder:
/etc/systemd/system/emqx.service.d/restart.conf
with the following content:
[Service]
Restart=always
RestartSec=10
In this way we achieve that a service contained in init.d can control both its startup and its subsequent reboot retry by systemd itself.
For more information about it:
https://singlebrook.com/2017/10/23/auto-restart-crashed-service-systemd/
https://www.freedesktop.org/software/systemd/man/systemd.service.html
https://www.digitalocean.com/community/tutorial_series/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot
start-stop-daemon starting multiple processes
The man page of start-stop-daemon contains a special warning on the usage of the --exec option with scripts.
-x, --exec executable
Check for processes that are instances of this executable. The executable
argument should be an absolute pathname. Note: this might not work as
intended with interpreted scripts, as the executable will point to the
interpreter.
When you run a script, the process that is actually launched is the interpreter noted in the shebang line of the script. This confuses the start-stop-daemon utility.
BTW, you can use the -t option to debug that kind of issues with start-stop-daemon.
Linux start-stop-daemon directory error calling shell/python script
Try calling cd
using an absolute path, for example /home/alexjg/
instead of ~/
; the reason it was broken before is that in your example you're using sudo
which keeps the home directory of the user running it. However when you're calling the bash script from init it will use root's home directory instead which doesn't contain test.py
.
The file is created because the redirection is still succeeding; however because starting Python failed there was no output.
Why start-stop-daemon needs privileges?
start-stop-daemon
can also set the user ID for the daemon process.
That said, you'd generally use start-stop-daemon
from a script in /etc/rc.d
, which is run with root privileges either from the init
system that is being used this week (sysvinit, upstart, systemd, ...) and/or from the service(8)
command.
So, if a user should be able to start/stop the service (which is a rather uncommon scenario), you'd use the sudoers
file to grant them access to the service
command, with the name of your service as a mandatory first argument.
In general though, write your service so it can be simply started at boot or during installation, and used by users as long as it's running. If the user needs to be able to start and stop instances of the service, then your daemon is in the business of managing instances, and the instance manager should be continually running, and users then contact this service via a socket (so users don't need sudo
at all, which would make the lives of many administrators who don't install sudo
quite a bit easier).
Not able to stop init script using start-stop-daemon
Regarding your comment, if you're willing to extend the shellscript you are running, you can use a pidfile. In practice, maybe you want to make it an option to your script, but as an example, this line would be sufficient:
echo $$ >/var/run/dev-myapp.sh.pid
Then, use these matching parameters for start-stop-daemon
, if necessary replacing /bin/bash
with whatever shell executes your script:
-p /var/run/dev-myapp.sh.pid -x /bin/bash
(To clarify: The process name of the script is that of the script interpreter, in your case, the shell)
Related Topics
Gdb: Redirect Target Stdout Temporarly
Dyld_Library_Path Environment Variable Is Not Forwarded to External Command in Makefile on MACos
Chrome Certificate Selection Appears Multiple Times
Using Ld_Preload Mixed 64Bit/32Bit Environment in Linux
Aslr Bits of Entropy of Mmap()
How to Use Global Arrays in Bash
In Bash, Why 'X=100 Echo $X' Doesn't Print Anything
Tiny "Manually" Created Elf Giving Segmentation Fault
Sed: Insert a Line in a Certain Position
How to Build an App for an Old Linux Distribution, and Avoid the Fatal: Kernel Too Old Error
How to Use Grep to Match But Without Printing the Matches
Have One Folder with Files That Have the Same Name But Different File
Identifying Which Linux System Library Contains a Function
How to Set a Variable Used in a Perl Script as Environment Variable
Why Does the Wc Command Count One More Character Than Expected
Concurrency of Posix Threads in Multiprocessor MAChine
Append Text to File from Command Line Without Using Io Redirection