ExecStart is geen shell: een VPN-hulpeenheid repareren
ExecStart start een programma met argumenten, geen shell-pipeline. Gebruik een expliciete interpreter of een echt script, verifieer daarna de unit en lees het journal.
Kopieer een werkende commandoregel naar ExecStart, herlaad, en de unit faalt of eindigt stil omdat de argumenten als bestandsnamen worden behandeld. Aan systemd is niets kapot. ExecStart is een argumentenlijst, geen shell, dus pijpen, omleiding en voorwaarden verliezen hun betekenis zodra ze je terminal verlaten. Bepaal waar de shell hoort, en schrijf dan een unit die precies zegt wat er moet worden uitgevoerd.
Waarom de pijplijn in ExecStart niets doet
Wanneer een opdracht in een terminal wordt getypt, parseert de shell die eerst. Hij bouwt een pijplijn, opent bestanden voor omleiding en breidt variabelen uit voordat er ook maar een programma start. systemd doet niets daarvan: het splitst ExecStart volgens zijn eigen regels en voert het resulterende programma met die argumenten uit. Daarom komt > als een letterlijk argument aan, en een | wordt aan het programma gegeven in plaats van twee processen te verbinden. De unit gedraagt zich niet verkeerd; de syntaxis bedoelde iets anders.
Dat is opzettelijk en niet slordig, want voorspelbare argumentafhandeling is wat units controleerbaar maakt. Het verrast alleen wie aanneemt dat er een shell is.
Schrijf een unit die precies zegt wat er draait
Begin met een kleine unit waarvan het doel zichtbaar is in het journal, zodat parseerproblemen gescheiden blijven van tunnelproblemen. Deze rapporteert alleen de versie van een binair bestand.
[Unit]
Description=Report the installed OpenVPN version
[Service]
Type=oneshot
ExecStart=/usr/sbin/openvpn --version
StandardOutput=journal
StandardError=journalHet pad is een plaatsaanduiding, vervang het dus door het daadwerkelijk geïnstalleerde binaire bestand. Type=oneshot past bij een opdracht die tot het einde draait, en de journalinstellingen zetten de uitvoer waar je die zonder terminal kunt lezen. Er is bewust geen installatiesectie, dus de unit wordt met de hand aangeroepen in plaats van bij het opstarten ingeschakeld. Valideer het bestand voordat je het start, want een typefout in een richtlijnnaam faalt anders dan een typefout in het pad.
systemd-analyze verify /etc/systemd/system/openvpn-version.service
systemctl start openvpn-version.serviceHoud shell-logica in een script
Wanneer een helper echt voorwaardelijke logica nodig heeft, zet die logica dan in een script en roep het expliciet aan. Het script heeft een interpreterregel, uitvoerrechten en exitcodes nodig die de dienst kan rapporteren. Het starten van /bin/sh -c met een opdracht tussen aanhalingstekens werkt, maar het verbergt aanhalingstekenregels in een unit en maakt beoordeling moeilijker. Een genoemd script kan met de hand worden getest en later worden vervangen zonder de unit te bewerken. Vertrouw niet op het shell-profiel van de interactieve gebruiker, want een dienst start met zijn eigen omgeving.
Stel WorkingDirectory in wanneer relatieve paden ertoe doen, en geef de omgeving door via de ondersteunde richtlijnen van de unit in plaats van die in een terminal te exporteren. Geheimen horen in beschermde bestanden of inloggegevens, niet in argumentenlijsten die het journal kan vastleggen.
Controleer de unit die echt bestaat
Drop-in-bestanden veranderen gedrag zonder het bestand aan te raken dat je je herinnert te hebben bewerkt. Lees wat de beheerder heeft geladen en wat de laatste run rapporteerde.
systemctl cat vpn-helper.service
journalctl -u vpn-helper.service -n 20 --no-pagerDe unit-dump bevat drop-in-bestanden in laadvolgorde, en daar komt een onverwachte ExecStart meestal vandaan. Herlaad na elke wijziging de beheerder en bevestig dat de nieuwe definitie is wat systemctl cat afdrukt. Het journal toont de exacte commandoregel en de exitstatus, wat een argumentprobleem scheidt van een ontbrekend binair bestand of een rechtenfout. Beslis daarna of de helper bij de bestaande VPN-levenscyclus hoort of een handmatige diagnose moet blijven, want een tweede tunneproces op de achtergrond maakt een concurrerende eigenaar.
Een unit die op verzoek de juiste uitvoer afdrukt, is een goede eerste mijlpaal. Het is nog geen tunnel, en het moet niet doen alsof.