Копирајте радни командни ред у ExecStart, поново учитајте и јединица пада или тихо излази јер се аргументи третирају као називи датотека. У systemd-у ништа није покварено. ExecStart је списак аргумената, а не shell, па цевоводи, преусмеравање и услови губе смисао оног тренутка кад напусте ваш терминал. Одлучите где припада shell, затим напишите јединицу која тачно каже шта се треба извршити.

Зашто цевовод у ExecStart-у не ради ништа

Кад се наредба упише у терминал, shell је прво рашчлањује. Гради цевовод, отвара датотеке за преусмеравање и проширује променљиве пре него што се покрене било који програм. systemd не ради ништа од тога: дели ExecStart према властитим правилима и извршава добијени програм са тим аргументима. Зато > долази као дословни аргумент, а | се предаје програму уместо да повеже два процеса. Јединица се не понаша погрешно; синтакса је значила нешто друго.

То је намерно, а не немаро, јер предвидиво руковање аргументима чини јединице проверљивим. Изненађује само оне који претпостављају да је shell присутан.

Напишите јединицу која тачно каже шта се покреће

Почните са малом јединицом чија је сврха видљива у дневнику, како би проблеми рашчламбе остали одвојени од проблема тунела. Ова само пријављује верзију бинарне датотеке.

[Unit]
Description=Report the installed OpenVPN version

[Service]
Type=oneshot
ExecStart=/usr/sbin/openvpn --version
StandardOutput=journal
StandardError=journal

Путања је заменски текст, па је замените бинарном датотеком која је стварно инсталирана. Type=oneshot одговара наредби која ради до завршетка, а поставке дневника стављају њен излаз тамо где га можете прочитати без терминала. Намерно нема одељка за инсталацију, па се јединица позива ручно уместо да се омогући при подизању. Проверите датотеку пре покретања, јер словна грешка у називу директиве пада другачије од грешке у путањи.

systemd-analyze verify /etc/systemd/system/openvpn-version.service
systemctl start openvpn-version.service

Задржите shell логику у скрипти

Кад помоћнику заиста треба условна логика, ставите ту логику у скрипту и позовите је изричито. Скрипти требају интерпретерски ред, дозвола за извршавање и излазни кодови које услуга може да пријави. Покретање /bin/sh -c са наредбом под наводницима заиста ради, али скрива правила навођења унутар јединице и отежава преглед. Именована скрипта може се ручно тестирати и касније заменити без уређивања јединице. Не ослањајте се на shell профил интерактивног корисника, јер услуга креће са сопственим окружењем.

Поставите WorkingDirectory кад су релативне путање важне, а окружење прослеђујте подржаним директивама јединице уместо да га извезете у терминалу. Тајне припадају заштићеним датотекама или акредитивима, а не списковима аргумената које дневник може да забележи.

Проверите јединицу која стварно постоји

Drop-in датотеке мењају понашање без дирања датотеке коју се сећате да сте уређивали. Прочитајте шта је управљач учитао и шта је пријавило последње покретање.

systemctl cat vpn-helper.service
journalctl -u vpn-helper.service -n 20 --no-pager

Испис јединице укључује drop-in датотеке по редоследу учитавања и управо одатле обично долази неочекивани ExecStart. Након сваке промене поново учитајте управљач и потврдите да је нова дефиниција оно што исписује systemctl cat. Дневник показује тачан командни ред и излазни статус, што одваја проблем са аргументима од недостајуће бинарне датотеке или грешке с дозволама. Затим одлучите припада ли помоћник постојећем животном циклусу VPN-а или треба да остане ручна дијагностика, јер други позадински процес тунела ствара конкурентног власника.

Јединица која на захтев исписује тачан излаз добар је први корак. Још није тунел и не би требало да се претвара да јесте.

Повезани чланци