Я не отримав mkfifo
хитрості працювати задовільно; він, схоже, не захопив stderr, і спроби перенаправити змусили Upstart під заставу без помилок.
Це також має невдалий побічний ефект - змусити logger
процес зависати в дитинстві init
, тому інформація про те, кому «належить» лісоруб, втрачається, і хто ще не знає про це, mkfifo
може припустити, що це звисаючий процес, який може бути вбитий.
Натомість я закінчив наступне рішення, яке вирішує всі ці питання. Це змушує logger
стати дочірнім процесом, зберігаючи службу як кореневий процес. На жаль, це вимагає виконання bash
, але воно виглядає просто брудно.
script
# ... setup commands here, e.g. environment, cd, ...
exec bash <<EOT
exec 1> >(logger -t myservice) 2>&1
exec myservice
EOT
end script
Для цього використовується трюк, який перенаправляє stdout та stderr до команди. Оскільки ми виконуємо службу всередині bash
команди, це має побічний ефект заміни оболонки і магічним чином перетворить bash на дочірній процес служби, як показано ps aufxw
:
myservice
\_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice
\_ logger -t myservice
Чомусь вищевказану команду потрібно загорнути в a bash -c
. Я припускаю, що це тому, що Upstart тільки робить вигляд, що запускає ваш сценарій через Bash, але насправді це не так. Якщо хтось може запропонувати спосіб уникнути зайвої оболонки, це було б приголомшливо.