Запуск сценария bash из systemd, как если бы я вошел в систему

У меня есть служба, реализованная в виде сценария Bash. Внутри это на самом деле приложение node.js, но для целей этого вопроса это может быть что угодно.

Основной вариант использования состоит в том, что мы разрабатываем / отлаживаем сценарий в интерактивной оболочке, а затем включаем его как службу.

Если я подключусь к своему устройству по ssh (вход в систему), вся моя среда будет там, и я могу запустить свой сценарий из командной строки, без проблем. Оболочка, в которой я нахожусь, подобрала правильную среду из .bashrc , .profile и т. Д., И все работает.

Но если я запускаю его из службы systemd, он источник среды, как и для интерактивной оболочки. Есть условия для добавления переменных среды в модуль, но то, что я здесь делаю, просто дублирует то, что делает моя интерактивная среда, и становится простым способом что-то забыть.

Я уверен, что для реальной производственной службы есть правильный способ сделать это, но это лабораторное приложение, и мне нужно упростить его, чтобы никто, работающий над сценарием, не знал, как работает systemd.

Итак, вопрос: что мне нужно сделать, чтобы сценарий, написанный для запуска в интерактивной оболочке Bash, запускался из systemd?

Я пытался запустить bash с помощью - login , но это не работает. Также явно не делается источник .bashrc во внешнем скрипте.

Вот пример, над которым я работаю, чтобы выделить проблему:

основной скрипт ( job.sh ):

#!/bin/bash
cd
while [ 1 ]
do
    pwd
    echo USER is $USER
    echo PATH is $PATH
    which node
    node --version
    sleep 1
done

Я вызываю его из другого скрипта ( wrapper.sh ):

#!/bin/bash
echo starting wrapper...
bash --login /home/droid/job.sh

и вот мой модуль job.service в /etc/systemd/system/job.service :

[Unit]
Description=Job Daemon

[Service]
User=droid
ExecStart=/home/droid/wrapper.sh

[Install]
WantedBy=multi-user.target

Что я не понимаю в systemd, что мешает мне заставить это работать?

1
задан 18 December 2017 в 10:29
2 ответа

Разница между выполнением скрипта через systemd и его непосредственным выполнением заключается в окружении. Вы можете протестировать его таким образом. В файле Unit добавьте это в раздел [Service] для тестирования:

StandardOutput=console

Затем в вашем скрипте bash, в верхней части добавьте эту строку для сброса окружения:

env

Теперь запустите скрипт внутри и вне systemd и сравните переменные окружения, которые были сброшены.

Это особенность systemd в том, что он жестко контролирует окружение. Это повышает безопасность и обеспечивает согласованность.

Вы можете прочитать больше о том, как systemd управляет окружением в systemd.exec.

Получить что-то одинаковое для запуска через CLI и через систему очень просто, как только вы запустите его, как только вы захотите из systemd. Запустите его через CLI следующим образом:

systemctl start your-unit-name

Тогда systemd будет работать с точно таким же окружением.

Вы просили обратного: Заставить systemd запустить службу, используя ваше "bash" окружение. Но это грязное, меняющееся окружение, которое может привести к противоречивым результатам. Напротив, окружение выполнения systemd строго контролируется, что приводит к последовательным, воспроизводимым результатам. Вот почему следует вывернуть вопрос наизнанку и спросить, как вы можете использовать ваши службы на CLI, используя ту же самую, последовательную, контролируемую среду выполнения, которую использует systemd.

1
ответ дан 3 December 2019 в 23:40

Хотя .profile читается любым экземпляром оболочки, .bashrc явно предназначен только для интерактивных оболочек без входа в систему. Действительно, в зависимости от вашего дистрибутива, по умолчанию .bashrc может иметь что-то вроде этого вверху, чтобы дополнительно убедиться, что файл обрабатывается только интерактивными оболочками:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Вероятно, поэтому ручной поиск .bashrc не помог. т работать.

Вероятно, вы могли бы заставить его работать, указав --login и убедившись, что необходимые переменные среды установлены в .profile, а не в .bashrc. Однако, вероятно, лучше было бы иметь отдельный файл переменных среды специально для этой службы и убедиться, что файл получен как из службы systemd, так и при ее запуске вручную.

1
ответ дан 27 January 2021 в 02:24

Теги

Похожие вопросы