В systemd (и других современных системах инициализации) запуск службы строго разделен на два этапа:
- Инструменты пользователя (например, systemctl) удаленно запрашивают init (pid 1) для запуска определенной службы.
- Init читает конфигурацию службы, настраивает среду (включая переключение на нужную учетную запись пользователя) и запускает исполняемый файл.
Из-за этой косвенности сервисы всегда будут иметь одинаковую среду независимо от того, кто и как их запустил. (Раньше обычная проблема - пользовательская среда, такая как контексты локали, пути или SELinux, просачивающиеся в сервисы).
(Для сценариев init.d файл lsb-functions дистрибутива содержит магические перенаправления на «запуск systemctl», поэтому они также получают ту же косвенную информацию.)
Это также означает, что вы не можете запустить службу «как тот же пользователь» - вы должны настроить конкретное имя пользователя в соответствующем файле systemd .service (и если его нет, вам действительно следует написать его).
Вызов 'start service' обычно является привилегированным, но вы можете написать правило polkit, разрешающее его для каждого пользователя или для каждого сервиса (если версия systemd достаточно свежая):
/* /etc/polkit-1/rules.d/allow-whatever.rules */ polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.systemd1.manage-units") { var verb = action.lookup("verb"); var unit = action.lookup("unit"); if (subject.user == "manager" && unit == "app.service" && (verb == "start" || verb == "stop" || verb == "restart")) { return polkit.Result.YES; } } });
В качестве альтернативы можно было бы отказаться от косвенного обращения в сценарии init.d, но тогда вы также полностью потеряете отслеживание службы systemd - ваш демон будет выглядеть как обычный пользовательский процесс.