6

A thing I frequently want to do is launch some long running process or server as my own non-privileged user and then have a way to tell if it's still running and restart it if not.

So for example I might set a cron job that runs every so often checking if my process is running and restart it if it has crashed. This is the essence of process management tools like djb's daemontools, supervisord, launchd etc. except that those tools are configured by default to run as root with config files in /etc but I would like a utility that lets me do the same sort of thing as my non-privileged user from the comfort of my home directory.

3

deamontools you mentioned work just fine as user. See https://cr.yp.to/daemontools/supervise.html

Update - solutions

as per the above suggestion the OP got this working using the svscan program from daemontools after trying two different methods:

  1. Put it in like this a modern crontab: @reboot /usr/bin/svscan $HOME/.local/service 2>&1 > $HOME/.local/service/log
  2. Make ~/.config/autostart/svscan.desktop with the Exec=... line set to launch svscan with a wrapper script. My wrapper script looks like this:

    #!/usr/bin/env sh
    (
      echo "Starting svscan."
      date
      /usr/bin/svscan $HOME/.local/service 2>&1
    ) >> $HOME/.local/service/log
    

Both methods work but each is good for a different situation. The first way is good if you're doing it on a headless machine where you want to allow a non-privileged user to install their own long running services and processes. The second way is good if you want all of the services to inherit the environment, ssh-agent etc. of your currently logged in X user, which means the processes effectively become a proxy of the currently logged in user themself.

  • Thank you - I should not be surprised to discover djb solved this problem correctly more than a decade ago. Thanks to your suggestion I found that I can use svscan to manage my long running services as my own user in a couple of ways (see above for update). – Chris McCormick Aug 20 '16 at 5:17
3

Using systemd:

1. Create a service unit configuration file

~/.config/systemd/user/<service_name>.service

[Unit]
Description=<Write some description here>

[Service]
ExecStart=<Write some command here>
Restart=always

[Install]
WantedBy=graphical.target

See man systemd.service and man systemd.unit for more options.

2. Enable service in userspace

$ systemctl --user enable <service_name>

3. Start it emmidiately and check it's status

$ systemctl --user start <service_name>
$ systemctl --user status <service_name>

4. Ensure it starts automatically

Now you can reload PC and login to your graphical environment, then check the service status again.

5. Enjoy!

2

If your server runs systemd, you can run services in user-space with systemd --user start myservice. The service files must the be placed in ~/.config/systemd/user/.

If you configure the Restart option of that service, systemd will automatically restart that service when it exits (with different configuration options).

Another option that is independent of systemd might by to start screen. You can check if a screen session exists by calling screen -list, and start if necessary (detached). You can "remotely" execute commands in screen with screen -S "$screen_session" -X stuff 'command\n'. You would then simply start the program in background in that screen session, and remember the PID in a variable.

The cron job uses screen's stuff command to check if the process is still running, and re-starting otherwise.

  • Thanks, the first suggestion seems like it would be great if I was a systemd user. The screen suggestion is an interesting hack! – Chris McCormick Aug 20 '16 at 5:14
1

On Debian systems you could use start-stop-daemon in similar way as it is used by init scripts. For daemonizing (double fork) and saving PID no additional privileges are required (however should you try to use any option requiring them, running the program as unprivileged user will fail).

To start your long running process:

/sbin/start-stop-daemon --start --pidfile /path/to/pidfile --make-pidfile \
                        --background --exec /path/to/executable -- options

Check the status:

/sbin/start-stop-daemon --status --pidfile /path/to/pidfile

Stop the process:

/sbin/start-stop-daemon --stop --pidfile /path/to/pidfile

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.