Getting a background process ID is easy to do from the prompt by going:
$ my_daemon &
$ echo $!
But what if I want to run it as a different user like:
su - joe -c "/path/to/my_daemon &;"
Now how can I capture the PID of my_daemon?
Succinctly - with a good deal of difficulty.
You have to arrange for the su'd shell to write the child PID to a file and then pick the output. Given that it will be 'joe' creating the file and not 'dex', that adds another layer of complexity.
The simplest solution is probably:
su - joe -c "/path/to/my_daemon & echo \$! > /tmp/su.joe.$$"
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$ # Probably fails - joe owns it, dex does not
The next solution involves using a spare file descriptor - number 3.
su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>/tmp/su.joe.$$
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$
If you're worried about interrupts etc (and you probably should be), then you trap things too:
tmp=/tmp/su.joe.$$
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>$tmp
bg=$(<$tmp)
rm -f $tmp
trap 0 1 2 3 13 15
(The caught signals are HUP, INT, QUIT, PIPE and TERM - plus 0 for shell exit.)
Warning: nice theory - untested code...
As long as the output from the background process is redirected, you can send the PID to stdout:
su "${user}" -c "${executable} > '${log_file}' 2>&1 & echo \$!"
The PID can then be redirected to a file owned by the first user, rather than the second user.
su "${user}" -c "${executable} > '${log_file}' 2>&1 & echo \$!" > "${pid_file}"
The log files do need to be owned by the second user to do it this way, though.
The approaches presented here didn't work for me. Here's what I did:
PID_FILE=/tmp/service_pid_file
su -m $SERVICE_USER -s /bin/bash -c "/path/to/executable $ARGS >/dev/null 2>&1 & echo \$! >$PID_FILE"
PID=`cat $PID_FILE`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With