Копирајте работна командна линија во 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 животен циклус или треба да остане рачна дијагностика, зашто втор позадински процес на тунел создава конкурентен сопственик.

Единица што на барање го печати точниот излез е добар прв чекор. Таа сѐ уште не е тунел и не треба да се претставува како таков.

Поврзани статии