Я создал сценарий в /etc/init.d/, который должен запускать несколько других сценариев от других (не привилегированных) пользователей из их домашних каталогов, как если бы они их запускали.
Я запускаю эти скрипты с помощью: sudo -b -u <username> <script_of_a_particular_user>
И это работает. Но для каждого пользовательского скрипта, который продолжает работать (например, некоторого сторожевого таймера), я вижу соответствующий родительский процесс sudo, все еще живущий и работающий от имени пользователя root. Это создает беспорядок в списке активных процессов.
Итак, мой вопрос: Как я могу запустить (разветвить) другой сценарий из существующего сценария bash от имени другого пользователя и оставить его как осиротевший (автономный) процесс?
Более подробное объяснение:
Я в основном пытаюсь предоставить другим пользователям на машине средство запуска чего-либо при запуске системы или выключении системы, запустив исполняемые файлы, найденные в соответствующих подкаталогах, найденных в их домашнем каталоге, с именами .startUp и .shutDown. Поскольку я не нашел других средств для этого, я написал свой сценарий bash, который делает именно это, и я настроил его как служебный сценарий (следуя примеру скелета) в /etc/init.d/, поэтому при его запуске с аргументом start он запускает все из каталогов .startUp, а когда он запускается с аргументом stop, он запускает все из каталогов .shutDown всех пользователей как их.
В качестве альтернативы мне также интересно, мог бы я использовать какое-то существующее решение для решения этой проблемы.
ОБНОВИТЬ
Я немного огляделся и нашел этот вопрос: https://unix.stackexchange.com/questions/22478/detach-a-daemon-using-sudo
Принял ответ там, чтобы использовать: sudo -u user sh -c "daemon & disown %1"
, у меня работает. Но я пробовал и без отречься% 1 и это то же самое. Вот что у меня работает, как я ожидал:
sudo -u <username> bash -c "<script_of_a_particular_user> &"
Мой дополнительный вопрос: почему это работает без отрицания? я все еще должен оставить отречься позвонить, несмотря ни на что, для какого-то потенциального особого случая?
ОБНОВЛЕНИЕ 2
По-видимому, это тоже работает:
su <username> -c "<script_of_a_particular_user> &"
Есть ли разница между этим вызовом и вызовом sudo? Я знаю, что это потенциально совершенно другой вопрос. Но поскольку я сам нахожу здесь ответы, может быть, ради этой темы кто-нибудь мог бы уточнить это здесь.
ОБНОВЛЕНИЕ 3
Оба этих метода с su или sudo теперь создают новый startpar процесс (отдельный процесс, который запускается от имени пользователя root) после загрузки машины. В списке процессов отображается как:
startpar -f -- <name_of_my_init.d_script>
Почему возникает этот процесс? Очевидно, я делаю что-то не так, поскольку ни в одном другом скрипте init.d этот процесс не запущен.
ОБНОВЛЕНИЕ 4
Проблема со startpar решена. Я задал для этого еще один вопрос:
Процесс startpar зависает при запуске процессов из rc.local или init.d
И еще вопрос для дальнейшего обсуждения механизмов запуска для непривилегированных пользователей:
Предоставление обычным пользователям (без полномочий root) возможности автоматического запуска инициализации и выключения
Правильный ответ на этот вопрос заключался в том, что для правильной "демонизации" стандартный ввод, стандартный вывод и стандартная ошибка должны быть перенаправлены в / dev / null (или в какой-то реальный файл):
su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"
вс - заменить идентификатор пользователя на какой-то пользователь
-c - аргумент su для запуска указанной команды
нету - Запустите команду, невосприимчивую к зависаниям. Чтобы предотвратить случаи, когда родительский процесс завершит дочерний процесс. Добавил сюда на всякий случай. Но на самом деле не имеет никакого эффекта в моем конкретном случае. Необходимость этого зависит от окружающей среды (отметьте купил)
> / dev / null - Перенаправить стандартный вывод в ничто, в основном отключив его.
2> & 1 - Перенаправить стандартный вывод ошибок (2) на стандартный вывод (1), который перенаправляется на нуль
& - отсоединить от фона, это перенаправит стандартный ввод также в / dev / null.
По сути, это именно то, что старт-стоп-демон утилита из Debian dpkg делает по своей сути. Вот почему я предпочитаю запускать скрипты таким образом, а не вводить в свой код еще один вызов внешней утилиты. старт-стоп-демон полезен в тех случаях, когда у вас есть полнофункциональные программы-демоны, которые вам нужно запустить, и где вам затем нужны дополнительные функции, которые старт-стоп-демон предоставляет (например, проверяет, запущен ли уже указанный процесс, чтобы он не запускал его снова).
Также стоит отметить, что вы также можете закрыть файловые дескрипторы вашего процесса вместо того, чтобы перенаправлять их на / dev / null, например:
su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"
0 <& - Закрыть стандартный ввод (0)
1> & - Закрыть стандартный вывод (1)
2> & - Закрыть стандартный вывод ошибки (2)
Направление знаков <> не имеет значения, если указан длинный номер дескриптора файла. Так что это одинаково хорошо:
su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"
или
su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"
Однако есть более короткий способ написать это без чисел для stdin и stdout, где направление имеет значение:
su someuser -c "some_script.sh <&- >&- 2>&- &"
Когда файловые дескрипторы закрываются или перенаправляются на / dev / null (старт-стоп-демон выполняет перенаправление на / dev / null) процесс можно безопасно запускать в фоновом режиме в качестве демона. Так вот что нужно, чтобы избежать проблем (startpar) с запуском скриптов во время загрузки.
Я реализовал все решение из своей первоначальной идеи и разместил его на GitHub:
https://github.com/ivankovacevic/userspaceServices
Вы можете использовать старт-стоп-демон вне init.d с помощью --user
вариант.
Я не тестировал это полностью, но думаю, что что-то вроде:
/sbin/start-stop-daemon --background --start --exec /home/USER/.startUp --user USER --pidfile=/home/USER/.startUp.pid --make-pidfile
при запуске, а затем
/sbin/start-stop-daemon --stop --user USER --pidfile=/home/USER/.startUp.pid
при выключении.
Обработка сценария .shutDown может выполняться чем-то вроде запуска, но вы не можете быть уверены, что сценарии работают до конца, поскольку выключение должно произойти в любом случае :-)
должен сработать, возможно, вам следует добавить перенаправление ввода, но тогда вам придется беспокоиться о заполнении файлов журнала.
Вы пробовали использовать su
?
su -c /home/user/.startUp/executable - user
-c
указывает su выполнить команду, и последний параметр - это пользователь, от имени которого она должна выполняться.