I'm working on an init script for Jetty on RHEL. Trying to use the
daemon --user="$DAEMON_USER" --pidfile="$PIDFILE" "$DAEMON $DAEMON_ARGS &"
pid=`ps -A | grep $NAME | cut -d" " -f2`
pid=`echo $pid | cut -d" " -f2`
if [ -n "$pid" ]; then
echo $pid > "$PIDFILE"
This answer is incorrect because it assumed
daemon was the libslack tool. It is actually an independent shell function defined by the RHEL init system. Please go with jnas' answer instead.
Based on the code we can backtrack what happened.
Someone thought they had to make the program invoked by
daemon background itself, so they added
&. This was wrong.
daemon examins the command string to look for shell metacharacters, and if so, runs the command as an argument to
sh -c. This is well intentioned, but bad design because it's unpredictable and error prone. In any case,
daemon now ends up executing
sh -c 'something &'.
daemon puts the pid of
sh in the pidfile.
sh, of course, immediately exits, because its only job was to background a command.
The person who wrote this example noticed that they couldn't control the daemon, because the pid file referred to the pid of now dead
sh instead of their daemon.
They decided to "fix" this by manually getting extracting the pid from
ps. This is where the
pid= lines comes from.
However, they found that this didn't always work. This is because there's a race condition between the daemon starting and
ps command running.
They decided to "fix" this by only writing the pid if it was find, and leaving the invalid pid otherwise. This is where the
if [ -n "$pid" ] condition comes from.
The way to fix this is simply to not have the daemon background itself, and let the
daemon command do that. The rest of the code is now useless.