Процесс startpar зависает при запуске процессов из rc.local или init.d
У меня есть специфическая проблема при запуске текущих (сервисоподобных) процессов из полнофункционального сценария init.d (стиль SysV) или простого однострочного вызова из файла rc.local, например:
su someuser -c "/home/someuser/watchdog.sh &"
Где watchdog.sh содержит это:
#!/bin/bash
cd /home/someuser
until ./eventMonitoring.py
do
echo "Program crashed with exit code $?. Starting again..." >&2
sleep 1
done
Я всегда остаюсь с одним дополнительным процессом в списке процессов:
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 3048 1 0 1024 620 1 20:04 ? 00:00:00 startpar -f -- rc.local
Если я запускаю его из моего скрипта init.d (источник: https://github.com/ivankovacevic/userspaceServices)
Я получаю тот же процесс, но это startpar -f - userspaceServices
Какого черта этот процесс? Почему нет упоминания аргумента -f при просмотре справочной страницы startpar? Что я делаю не так с точки зрения запуска процесса при загрузке от имени другого пользователя, что этот странный процесс startpar также нужно оставить (или запустить)? Почему этот процесс отсутствует для любого другого сценария init.d?
Может кто-нибудь помочь мне пролить свет на эту тему?
Примечание. Моя система - Debian Wheezy 7.4.0.
ОБНОВИТЬ!
Я открыл новый вопрос по stackoverflow, чтобы обсудить поведение startpar с точки зрения программистов:
https://stackoverflow.com/questions/22840360/figuring-out-what-startpar-c-sysvinit-is-doing
1 ответ
Мои дальнейшие исследования привели меня к решению. Так что теперь я знаю, как сделать это правильно, но я до сих пор не понимаю, почему startpar вел себя так, как он. Поэтому, если кто-то захочет вмешаться и объяснить это, я более чем готов принять этот ответ, чем этот.
В основном проблема заключалась в том, что я вызывал сценарии без перенаправления (или закрытия) стандартного ввода, стандартного вывода и стандартной ошибки в файл или в /dev/null и по какой-то причине startpar("используется для параллельного запуска нескольких сценариев уровня выполнения")) процесс, который, насколько я понимаю, запускает другие процессы во время загрузки, был заблокирован в моем сценарии из-за этого. Он запустил мой скрипт, но сам не запустился и остался на этапе, показанном в списке процессов как:
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 3048 1 0 1024 620 1 20:04 ? 00:00:00 startpar -f -- rc.local
Исходный код startpar находится здесь: http://svn.savannah.nongnu.org/viewvc/startpar/trunk/startpar.c?root=sysvinit&view=markup
Я просмотрел его и сделал свой начальный анализ в новом вопросе, который я разместил в stackoverflow. Найдите ссылку в ОБНОВЛЕНИИ, которую я добавил к моему вопросу здесь.
Окончательное решение, которое я использовал, это:
su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"
su - заменить идентификатор пользователя на someuser
-c - аргумент su для запуска указанной команды
nohup - Запустите команду, невосприимчивую к зависаниям. Для предотвращения случаев, когда родительский процесс завершит дочерний процесс. Добавлено здесь на всякий случай. Но на самом деле не имеет никакого эффекта в моем конкретном случае. Нужно ли это, зависит от окружающей среды (проверьте покупателя)
> /dev/null - Перенаправить стандартный вывод в ничто, отключив его.
2> & 1 - Перенаправить стандартный вывод ошибки (2) на стандартный вывод (1), который перенаправляется на ноль
& - отсоединиться от фона, это перенаправит стандартный ввод также в /dev/null.
Глядя на файловые дескрипторы других известных демонов, работающих в моей системе, я вижу, что перенаправление в /dev/null является обычным делом. И только некоторые процессы-демоны фактически полностью закрыли stdin, stdout, stderr. Что, например, может быть достигнуто этим:
su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"
В практическом смысле это все то же самое, и это то, что нужно (любой вариант), чтобы чисто отделить процесс как фоновый демон.