У меня есть короткий скрипт в bash, который нужно запускать как демон в фоновом режиме. Он основан на inotifywait, который должен ждать изменений в указанной папке и в случае каких-либо изменений запускать процесс копирования.
#! /bin/sh
case "$1" in
start)
dir=/var/www/www/source/
target=/var/www/www/htdocs/application/cache/target/
inotifywait -m "$dir" --format '%w%f' -e close_write |
while read file; do
cp "$file" "$target"
done
;;
stop)
;;
esac
Я уже поместил его в /etc/init.d после запуска сохранения update-rc.d значения по умолчанию myscript, но теперь, когда я пытаюсь запустить, он бросает команду запуска службы, он перестает зависать в сообщениях от inotifywait.
/etc/init.d/bash start
Setting up watches.
Watches established.
Не могли бы вы подсказать, как запустить его в фоновом режиме без каких-либо выходных сообщений (в идеале сразу после запуска)?
Вы могли бы использовать экран, или, как предлагается в комментарии, нету. Любой из них можно использовать автоматически, например, с помощью сценария инициализации.
В случае screen вам может потребоваться особая осторожность, он успешно откроет сеанс экрана, если используется из чего-то вроде сценария инициализации. В частности, установка правильного окружения $ TERM и запуск его от имени конкретного пользователя.
Если все сделано правильно, у него есть дополнительное преимущество - присоединение к сеансу экрана и его отсоединение. Хотя для вашей конкретной цели экран может быть немного излишним.
Также взгляните на /etc/init.d/skeleton который предоставляет шаблон для создания сценариев инициализации.
Следующая строка, часть do_start () функция может делать то, что вам нужно:
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON
Вам нужно только изменить переменные в начале, чтобы они указывали на ваш скрипт и связанные с ним вещи, и он мог бы работать как есть.
Один из возможных подходов - использовать DAEMON Tools чтобы запустить ваш сценарий bash. Daemontools - это демон, который контролирует выполнение вашего скрипта - слушает его стандартный вывод и перезапускается, если он завершается. Также есть альтернативы, такие как руководитель или запустите свой скрипт с Сервисный блок systemd
Так что я заставил это работать, но это довольно уродливый хакер. О том, как правильно писать сценарии инициализации, я предложить эту ссылку.
Я хотел просто поместить процесс на задний план с помощью «&».
/etc/init.d/myinitscript.sh
#! /bin/sh
case "$1" in
start)
dir=/var/www/www/source/
target=/var/www/www/htdocs/application/cache/target/
inotifywait -m "$dir" --format '%w%f' -e close_write |
while read file; do
cp "$file" "$target"
done & ## <--- why not just put it in the background?
;;
stop)
;;
esac
Это «работает» ... для определенных значений «работы». «myinitscript.sh» запускается при запуске и делает то, что должен делать, но приводит к зависанию процесса:
$ ps aux | grep -i init
[... snip ...]
root 2341 0.0 0.1 4096 600 ? Ss 18:02 0:00 startpar -f -- myinitscript.sh
[... snip ...]
Причина и возможные решения этой проблемы можно найти здесь.
Мое последующее решение уродливо, и если вы делаете это в производственной среде, значит, вы делаете это неправильно.
Я использую два скрипта, один в /etc/init.d, а другой в / root.
/etc/init.d/myinitscript.sh
#! /bin/sh
case "$1" in
start)
/root/initscriptbody.sh > /dev/null 2>&1
;;
stop)
;;
esac
Отсутствие перенаправления stdout и stderr в / dev / null приводит к зависанию процесса 'starpar'. Второй скрипт содержит всю функциональность, и именно здесь он может быть помещен в фоновый режим без зависания процесса 'starpar':
/root/initscriptbody.sh
#! /bin/sh
dir=/var/www/www/source/
target=/var/www/www/htdocs/application/cache/target/
inotifywait -m "$dir" --format '%w%f' -e close_write |
while read file
do
cp "$file" "$target"
done & ## <-- no problem backgrounding this now