Вопрос или проблема
Я пытался настроить файл службы для нашего программного обеспечения, чтобы его можно было запускать и останавливать. Когда я вручную выполняю команды, сервер начинает работать нормально. Затем я реализовал это в скрипте bash, и он также начинает работать нормально. Скрипт bash:
#!/bin/bash
/bin/cd /opt/software/test/; source software_env.sh
export TEST_APP="/opt/software/testapp"
/bin/cd /opt/sotware/test/bin/; startserver
Я попробовал просто внедрить эти команды в системный файл, но не смог этого сделать. Следующая попытка заключалась в том, чтобы оставить скрипт bash и вызвать его из системного файла, который выглядел следующим образом:
[Unit]
Description=Тестовая служба
[Service]
Type=forking
ExecStart=/opt/software/test/test.startup
[Install]
WantedBy=multi-user.target
Я также пытался установить тип службы как Type=simple
, но это тоже не сработало. Я могу успешно запустить сервер, запуская скрипт bash через cron при перезагрузке, но если есть способ запустить этот скрипт bash в файле службы, это именно то, что я хочу сделать.
Сложность, похоже, заключается в том, чтобы корректно работать с source и export в файле единицы. Я также заметил некоторое странное поведение, когда пытался заставить скрипт bash работать; выполнение: source /opt/software/test/software_env.sh
вместо /bin/cd /opt/software/test/; source software_env.sh
не сработало.
Ошибка от systemd, независимо от различных техник, которые я пробовал, чтобы это запустить, давала одну и ту же ошибку.
test.service - Тестовая служба
Loaded: bad-setting (Причина: у единицы test.service неправильная настройка файла единицы.)
Active: failed (Результат: exit-code)
Main PID: 2778 (code=exited, status)
Спасибо за любые и все предложения.
Я не знаю, как выглядит ваш файл источника, но если он имеет простой формат VAR=VALUE, то вы можете использовать функцию EnvironmentFile.
[Service]
EnvironmentFile=/opt/software/test/software_env.sh
WorkingDirectory=/opt/software/test
Environment=TEST_APP=/opt/software/testapp
Type=forking
ExecStart=/opt/software/test/test.startup
systemd не может принимать оболочечные команды напрямую. Вы можете передать какой-то способ выполнения оболочки для загрузки файла. В вашем случае вы можете попробовать изменить вашу единицу так:
ExecStart=/bin/sh -c '. /opt/software/test/software_env.sh'
Freedesktop имеет руководство по systemd, вы можете ознакомиться с ним.
Ответ или решение
Настройка systemd для запуска приложения с использованием source
и export
Ваша задача заключается в том, чтобы запустить сервис через unit-файл systemd, который корректно обрабатывает команду source
и переменные окружения, которые вы корпоративно настраиваете. Давайте пошагово разберемся, как это сделать корректно.
1. Проблема
Первая проблема, с которой вы столкнулись, заключается в том, что unit-файлы systemd не могут напрямую выполнять команды оболочки, такие как source
. Вместо этого требуется использовать альтернативные методы для считывания и применения переменных окружения.
2. Использование EnvironmentFile
Если ваш файл software_env.sh
содержит простые переменные в формате VAR=VALUE
, то одним из лучших способов будет использовать поле EnvironmentFile
в секции [Service]
. Пример может выглядеть следующим образом:
[Unit]
Description=Test Service
[Service]
Type=forking
WorkingDirectory=/opt/software/test
EnvironmentFile=/opt/software/test/software_env.sh
Environment=TEST_APP=/opt/software/testapp
ExecStart=/opt/software/test/test.startup
[Install]
WantedBy=multi-user.target
В этом примере:
WorkingDirectory
указывает рабочий каталог, что позволяет избежать проблем с путями.EnvironmentFile
загружает переменные окружения из файла.Environment
устанавливает переменнуюTEST_APP
.
3. Использование /bin/sh -c
Если ваш файл software_env.sh
использует более сложные конструкции, которые не поддерживаются в формате EnvironmentFile
, вы можете выполнить следующие шаги:
[Unit]
Description=Test Service
[Service]
Type=forking
WorkingDirectory=/opt/software/test
ExecStart=/bin/sh -c '. /opt/software/test/software_env.sh; startserver'
[Install]
WantedBy=multi-user.target
Здесь:
ExecStart
включает/bin/sh -c
, который выполняет команды оболочки. Убедитесь, что все команды, необходимые для старта сервера, указаны правильно.
4. Установка и запуск сервиса
После того как unit-файл готов, выполните следующие команды для его установки и активации:
sudo systemctl daemon-reload # Перезагрузить конфигурацию systemd
sudo systemctl enable test.service # Включить сервис при запуске
sudo systemctl start test.service # Запустить сервис
5. Проверка статуса сервиса
Для проверки статуса вашего сервиса вы можете использовать:
sudo systemctl status test.service
Это даст вам информацию о том, работает ли сервис и какие ошибки, если они есть, возникли.
Заключение
Запуск сервисов через systemd может быть непростой задачей, особенно когда возникнут проблемы с переменными окружения и путями. Применяя предложенные подходы, вы сможете успешно интегрировать ваш скрипт запуска в систему управления сервисами Linux. Если возникнут дополнительные вопросы или трудности, не стесняйтесь обращаться за помощью.