Назад | Перейти на главную страницу

Сценарий bash как демон на debian

У меня есть короткий скрипт в 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