Starting a script as another user

The correct answer for this was that for proper "daemonization", standard input, standard output and standard error need to be redirected to /dev/null (or some real file):

su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"

su - substitute user identity to someuser
-c - su argument to run specified command
nohup - Run a command immune to hangups. To prevent cases where parent process will terminate the child process. Added here just in case. But actually has no effect in my particular case. Whether it is needed depends on the environment(check shopt)
>/dev/null - Redirect standard output to nothing, basically disabling it.
2>&1 - Redirect standard error(2) output to standard output(1), which is redirected to null
& - detach to background, this will redirect standard input also to /dev/null.

This is essentially exactly what start-stop-daemon utility from Debian dpkg does at its core. That is why I prefer starting scripts in this way rather then introducing another external utility call in my code. start-stop-daemon is useful in cases where you have full blown daemon programs that you need to start and where you then need additional functionality that start-stop-daemon provides (for example checking if the specified process is already running so that it doesn't launch it again).

It is also worth noting that you can also close file descriptors of your process instead of redirecting them to /dev/null, for example:

su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"

0<&- Close standard input(0)
1>&- Close standard output(1)
2>&- Close standard error(2) output

The direction of < > signs does not matter as long file descriptor number is specified. So this is equally good:

su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"

or

su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"

However there is a bit shorter way to write that, without numbers for stdin and stdout, where direction does matter:

su someuser -c "some_script.sh <&- >&- 2>&- &" 

When the file descriptors are either closed or redirected to /dev/null (start-stop-daemon is doing the redirection to /dev/null) the process is safe to run in background as a daemon. So that is what is needed to avoid problems(startpar) with launching scripts during boot time.

I've implemented the whole solution from my initial idea and placed it on GitHub:
https://github.com/ivankovacevic/userspaceServices


You can use the start-stop-daemon out of init.d with the --user option.


I haven't fully tested this, but I think that something like:

/sbin/start-stop-daemon --background --start --exec /home/USER/.startUp --user USER --pidfile=/home/USER/.startUp.pid --make-pidfile

at startup and then

/sbin/start-stop-daemon --stop --user USER --pidfile=/home/USER/.startUp.pid

when shutting down.

Handling the .shutDown script could be done by something like the startup thing, but you cant be sure that the scripts run to end since shutdown should happen anyway :-)

should do the trick, perhaps you should throw in some input redirection, but then you would have to worry about log files being filled.


Have you tried using su?

su -c /home/user/.startUp/executable - user

-c tells su to execute the command, and the last parameter is the user to execute it as.