Easy way of daemonizing in CentOS 5.4
Solution 1
You don't need anything special to make a daemon, really. Any program in any language can "daemonize" itself. Alternatively, you can daemonize an existing program with a small shell script wrapper (for instance the /etc/init.d program launcher can take care of it).
Typically, a daemon has the following properties :
- working directory must be /
- STDIN must be /dev/null
- STDOUT and STDERR must be either /dev/null or log files
- the parent ID should be init ( 1 ), easily achieved by forking then letting the parent exit.
Update 1
Monit basically takes care of the gory details I gave here. For the details about STDIN/STDOUT, /dev/null etc. these are basic Unix concepts so I guess you'll need to dig into this sooner or later. See for instance this Unix introduction.
Update 2
A shell script that daemonize a program would look like the following. Note that this will not work for programs that stay in the foreground.
#!/bin/sh
DAEMON=/some/program/to/run
PARAMETERS="parameters to my program"
LOGFILE=/var/log/somefile.log
start() {
echo -n "starting up $DAEMON"
RUN=`cd / && $DAEMON $PARAMETERS > $LOGFILE 2>&1`
if [ "$?" -eq 0 ]; then
echo "Done."
else
echo "FAILED."
fi
}
stop() {
killall $DAEMON
}
status() {
killall -0 $DAEMON
if [ "$?" -eq 0 ]; then
echo "Running."
else
echo "Not Running."
fi
}
case "$1" in
start)
start
;;
restart)
stop
sleep 2
start
;;
stop)
stop
;;
status)
status
;;
*)
echo "usage : $0 start|restart|stop|status"
;;
esac
exit 0
Solution 2
To start a script in non-interacting session, use nohup
(it will detach your process in a standalone term).
To make your script executable, use chmod ugoa+x <script_name>
.
The last point, do not use #!/bin/bash
or #!/bin/sh
because you don't know if resides in /bin
; try using #!/usr/bin/env bash
(or sh
) which forces the process to work under bash (sh) environment. Note that env
exists all the time in /usr/bin
and has all the environments (BASH, SH, TCSH...) paths registered in it.
Solution 3
If you are trying to daemonize a program that doesn't have a daemon mode then you can use daemonize. There are RPM packages for it in the repoforge repository.
Solution 4
The stdout of a daemon does not go to the terminal. If you simply want to automate restarting your program, I would suggest writing a shell script to perform the exact steps you are performing manually now.
Edit:
Here is a simple example shell script:
#!/bin/sh
do-start-stuff () {
stuff-to-do
}
do-stop-stuff () {
stuff-to-do
}
case "$1" in
start)
do-start-stuff
;;
stop)
do-stop-stuff
;;
restart)
do-stop-stuff
do-start-stuff
;;
esac
Related videos on Youtube
Saif Bechan
I am a Full Stack Web Developer with industry experience building websites and web applications. I specialize in JavaScript and have professional experience in working with PHP, Symfony, NodeJS, React, Redux and Apollo GraphQL. To ensure high quality and standards I have extensive knowledge on CI/CD pipelines such as GitLab CI and testing frameworks such as JUnit, PHPUnit and Cypress.
Updated on September 17, 2022Comments
-
Saif Bechan over 1 year
I know there is a program called upstart that can make it easy to make small daemons. I can't get this program to configure on CentOS. I get all sort of errors concerning pkg-congfig, libnih, and dbus.
I am working on a node.ja application and this is a pain to start and stop all the time, so I want to create a deamon for this which makes it easy to start and stop.
Update 1
I will give a small example of what i need for this project, I hope someone can help with this.To start the node.js application I have to type in SSH:
# node /path-to-file/filename.js
Now when I execute this the terminal freezez, i have to press CTRL + Z (pc) to get input back.
Now when i changed something in the file I have to reload it again
I need to:
# killall -9 node
This kills all the node applications that are running
Next i have to start the script again
# node /path-to-file/filename.js
I want to just type
# myapp restart
And everything is done. This type of setup would save me lots of time
Update 2
I found a program called monit. This works nice, and automatically starts the application in case of a crash, which is good. It also has a nice web interface which is also handy.I can type
# monit myapp start(start/stop/restart)
This works fine. There is only one downside, and this is a major downside. When i start the myapp application, it does not display the compile errors node.js throws. So when it fails to start I will not know what the reason is. I have to type the whole '# node /path-to-file/filename.js' again to check the error.
-
Saif Bechan about 14 yearsOk i am new to linux, so I don't know what all those tings are. Can you maybe give me a little example on how to achieve this. I will edit the question a little and maybe you can help me with this particular type of setup, because i have no idea what stdin, etc are.
-
Saif Bechan about 14 yearsCan you point me in some direction on how to create a shell script.
-
Saif Bechan about 14 yearsOk so basically I just create a file(myapp), and just add #!/bin/sh to the top of the line. And when I type the filename it will run as a program?
-
Dennis Williamson about 14 yearsYes, you can have
if
and other statements. See my edit. -
Saif Bechan about 14 yearsThank you for the help I will examine the code and I get the basic idea now. Thank you for the help. +1 for the answer.The answer of wazoox was slightly more detailed, thats why I accepted it answer.
-
Saif Bechan about 14 yearsThank you this will get me started on the program. Thank you for the help. Accepted answer
-
kmarsh about 14 yearsGood answer, though I would add that the parent process should ignore SIGCHLD in order for init to immediately inherit the orphan process and not leave a zombie in the process table. This is easily done in scripts using the NOHUP command, but like you said, tie up all 3 standard IO as well.
-
Saif Bechan about 14 yearsThis works great. I now have full control over the start and stop of the execution. This will save me a huge amount of time.
-
wazoox about 14 yearsYou're welcome :) you can use this script as /etc/init.d/yourapp and use your application as a full-fledged service from now. Error messages will go to the log file ( /var/log/whatever).
-
Saif Bechan over 12 years@slhck you didn't actually edit something, you just wrote down the exact same words. I am going to flag this for moderation attention.
-
DMA57361 over 12 years@Saif slhck changed those words in to monospace code items - so
#!/bin/bash
instead of #!/bin/bash - and added paragraph divisions. The post looks visually easier to parse, I see nothing wrong with this edit. -
slhck over 12 years@Saif As DMA said, that was the intention. If you have a problem with this, please explain yourself on Meta Super User…
-
wazoox about 12 years@woot, chdir to /root is essential to not prevent unmounting something inadvertently.