I have this proprietary program called lightid and I would like to run it as a daemon. The developer of lightid added a "-d" switch to the command line options to be able to run it as a daemon. Using sample-service-script, I created a proper start/stop bash script and installed it as a service in order to be able to control it using service lightid start service lightid stop service lightid status etc... and most importantly this way I can check its status using monit. The start function of the bash script (to be put in /etc/init.d/lightid) looks something like this
SCRIPT="/home/foo/lightid -d"
RUNAS=giulio
NAME=lightid
PIDFILE=/var/run/$NAME.pid
LOGFILE="/dev/null"
CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
su -c "$CMD" $RUNAS > "$PIDFILE"
as you can see, the su command is supposed to return the pid of the daemon so that this can be written to $PIDFILE, and its status can be checked using PID=$(cat $PIDFILE) ps axf | grep ${PID} | grep -v grep and the daemon can be killed using kill -15 $(cat "$PIDFILE")
The issue is that the line above su -c "$CMD" $RUNAS > "$PIDFILE"
writes to $PIDFILE
a pid that is not the same of the process that is running in the background. For instance, it would return 9933 whereas the process running in the background would have pid=9935 . The actual pid is always the returned value +2.
I asked the developer of lightid what its "-d" switch actually does and if this could be somehow the reason why the actual pid differs from the one returned by su. In fact, I suspect that the returned pid is the one of the parent process which terminates as soon as it "daemonizes" itself after the fork. He replied to me
"The reason I create the daemon the way I do is because that's what's documented in Michael Kerrisk's book The Linux Programming Interface. The reasons he gives are:
1.) By forking and terminating the parent the child becomes a child of the init process.
2.) The child needs to call setsid to start a new session and free itself from the controlling terminal.
3.) The second fork ensures the process is not a session leader and thus can't re-acquire the controlling terminal (System V requirement).
I've never come across a means of creating a daemon without forking so the problem of getting the processes PID the way you want to is, I'm afraid, not something I've dealt with before."
Is there any way I can get the correct pid? Should I just run lightid in non-daemon mode by appropriately redirecting stdin,stdout and stderr to /dev/null ?
CMD
seems full of opportunities for problems. What happes if you just runsu -c $SCRIPT &> $LOGFILE &
followed byecho $! > $PIDFILE
on a separate line? Good luck. – shellter