Запис файлу системного блоку із встановленим середовищем виконуваним шляхом


17

Я пишу файл системного блоку для програми Java, і я хотів би контролювати версію Java, яка використовується для її запуску. Мій (спрощений) сервісний файл є

[Service]
Type=simple
EnvironmentFile=%h/Documents/apps/app/app-%i/app.cfg
ExecStart=${JAVA_HOME}/bin/java ${JAVA_OPTS} -jar %h/Documents/apps/app/app-%i/myapp.jar
SuccessExitStatus=143

При спробі його запуску я отримую помилку назад

Apr 28 12:43:37 rombert systemd[1613]: [/home/robert/.config/systemd/user/app@.service:7] Executable path is not absolute, ignoring: ${JAVA_HOME}/bin/java ${JAVA_OPT
Apr 28 12:43:37 rombert systemd[1613]: app@1.0.0.service lacks both ExecStart= and ExecStop= setting. Refusing.

Я знаю, що JAVA_HOMEправильно встановлено; якщо я зміню ExecStartрядок для початку, /usr/bin/javaа потім додаю щось на зразок, -DsomeOption=${JAVA_HOME}я можу це бачити просто чудово.

Очевидним рішенням є створення скрипту для обгортки, але я вважаю, що це перешкоджає використанню сервісного файлу.

Як я можу встановити JAVA_HOME для програми Java за допомогою файлу одиниці?


Чому саме скрипт обгортки перемагає мета використання сервісного файлу? Ви все ще отримуєте послідовність системного відстеження та відстеження залежностей, моніторинг тощо. В основному, systemd торгує програмованістю у вільній формі, яку ми мали із SysVinit, на користь висунутої логіки DTRT . Коли "правильна річ" щось не робиться systemd, вам потрібно поставити це за межами systemd, як у сценарії оболонки.
Воррен Янг

@WarrenYoung - тому що я раптом знову починаю керувати скриптами оболонки. У моєму випадку керування скриптом оболонки корисніше, ніж інші біти.
Роберт Мунтяну

Я справді не бачу проблеми. Чи проводите ви свої дні, переживаючи про всі виконувані файли, якими також потрібно керувати? :)
Warren Young

3
Від systemd.service (5): "Зауважте, що перший аргумент (тобто програма для виконання) може бути не змінною." Це пояснює, чому $ {JAVA_HOME} не розгортається на початку шляху програми, а використовується, коли він використовується в якийсь пізній момент.
Віланд

@WarrenYoung - я віддаю перевагу одній обгортці над двійковим. Я розумію, що це питання не для всіх, але це для мене :-)
Роберт Мунтяну,

Відповіді:


12

З розділу "Командні рядки" в systemd.service (5):

Зауважте, що перший аргумент (тобто програма для виконання) може бути не змінною.

Я збирався запропонувати використовувати специфікатор примірника %i(ви можете прочитати більше про це у systemd.unit (5)), але (зараз ми знову в systemd.service (5)):

перший аргумент командного рядка (тобто програма для виконання) може не містити специфікаторів.

Я думаю, що найкращим варіантом на даний момент є дійсно створення скрипта оболонки, який завершує виконання двійкового файлу Java, як запропонував Уоррен Янг, або ви можете ExecStart оболонки безпосередньо, як у прикладі для командних рядків оболонки в розділі "Командні лінії" systemd.service (5), який має такий приклад:

ExecStart=/bin/sh -c 'dmesg | tac'

щоб ви могли зробити (неперевірено):

ExecStart=/bin/sh -c '${JAVA_HOME}....'

2

Ще один подібний варіант - використовувати /usr/bin/env:

ExecStart=/usr/bin/env "${JAVA_HOME}/bin/java" -jar ...

Таким чином можна опустити ' цитати навколо всієї команди, що корисно, якщо вам потрібно вкладати цитовані речі.

PS. Як бічна примітка, важливо укладати імена змінних в {дужки }в файли Systemd, інакше вони не будуть розпізнані правильно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.