Я не заставил 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
По какой-то причине вышеупомянутая команда должна быть заключена в bash -c
. Я предполагаю, что это потому, что Upstart только делает вид, что запускает ваш скрипт через Bash, но на самом деле это не так. Если кто-нибудь может предложить способ избежать дополнительной оболочки bash, это было бы здорово.