2

Я пытаюсь установить дату внутри файла модуля для регистрации

мой файл модуля выглядит так:

[Unit]
Description=Jetty service
After=multiuser.target

[Service]
Environment=MAIN_CLASS="com.candorgrc.nphase.MainJetty"
Type=simple
User=jetty
Group=jetty
WorkingDirectory=/home/jetty/dist
PermissionsStartOnly=true
ExecStartPre=/bin/systemctl set-environment date=$(/bin/date +%%Y-%%m-%%d-%%H-%%M)
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -Djava.util.logging.config.file=/home/jetty/logging.properties -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/u01/jetty/hdumps/hdump_${date} -verbose:gc -Dcom.sun.management.jmxremote.port=12321 -Dcom.sun.management.jmxremote.authen
PIDFile=/var/run/jetty.pid
ExecReload=/bin/kill -HUP $MAINPID
#Restart=on-failure
ExecStop=/bin/kill -9 $MAINPID

Установка даты не работает. Я получаю следующую ошибку:

Nov 26 16:47:50 vps203756 systemctl[14275]: Failed to set environment: Invalid environment assignments
Nov 26 16:47:50 vps203756 systemd[1]: jetty.service: Control process exited, code=exited status=1
Nov 26 16:47:50 vps203756 systemd[1]: jetty.service: Failed with result 'exit-code'.
Nov 26 16:47:50 vps203756 systemd[1]: Failed to start Jetty service.

Есть идеи, как настроить его для работы?

1 ответ1

1

Команды в ExecStart= в системных единицах systemd на самом деле не выполняются в оболочке, поэтому расширения оболочки (такие как подстановка команд $(...) вы там используете) в действительности недоступны.

Вы можете использовать их, явно вызвав скрипт оболочки с помощью /bin/sh -c '...' в вашем ExecStartPre= . Например:

ExecStartPre=/bin/sh -c 'systemctl set-environment date=$$(/bin/date +%%Y-%%m-%%d-%%H-%%M)'

Обратите внимание, что вам нужно экранировать саму $ , используя $$ , иначе systemd попытается интерпретировать как расширение переменной systemd. (На самом деле, как следующий символ ( один $ может работать там, но удвоение это более правильная установка.)

Обратите внимание, что использование systemctl set-environment как и вы, на самом деле не рекомендуется, так как вы создаете глобальную переменную среды ${date} которая будет доступна везде.

Вместо этого рассмотрите возможность запуска вашей команды ExecStart= через оболочку, и в этом случае вы можете определить переменную оболочки ${date} и просто использовать ее в единственном месте, где вам это нужно:

ExecStart=/bin/sh -c 'date=$$(/bin/date +%%Y-%%m-%%d-%%H-%%M); exec java -Xms512m -Xmx1024m ... -XX:HeapDumpPath=/u01/jetty/hdumps/hdump_$${date} -verbose:gc ...

Отметьте еще раз, экранируя $ с $${date} , поэтому systemd не считает, что это системная переменная для расширения. Кроме того, используя exec чтобы убедиться, что оболочка заменена процессом java , убедитесь, что systemd будет знать, какой PID является основным.

Выход на systemd ExecStart= может стать сложным и обременительным довольно быстро ... Поэтому попробуйте вместо этого сохранить сценарий оболочки в файле (в этом случае вам не нужно беспокоиться о экранировании от $ и % и о том, как кавычки могут работать немного по-другому), и просто запустите этот скрипт из ExecStart= , это намного проще (хотя для этого требуется дополнительный файл ...)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .