Kopier en fungerende kommandolinje inn i ExecStart, last inn på nytt, og enheten feiler eller avslutter stille fordi argumentene behandles som filnavn. Ingenting er ødelagt i systemd. ExecStart er en argumentliste, ikke et skall, så rør, omdirigering og betingelser mister betydningen i det øyeblikket de forlater terminalen din. Bestem hvor skallet hører hjemme, og skriv deretter en enhet som sier nøyaktig hva som skal kjøres.

Hvorfor røret i ExecStart ikke gjør noe

Når en kommando skrives i en terminal, parser skallet den først. Det bygger et rør, åpner filer for omdirigering og utvider variabler før noe program starter. systemd gjør ingenting av dette: det deler ExecStart etter sine egne regler og kjører programmet som blir resultatet med de argumentene. Derfor kommer > som et bokstavelig argument, og et | gis videre til programmet i stedet for å koble to prosesser. Enheten oppfører seg ikke feil; syntaksen mente noe annet.

Det er bevisst og ikke slurv, fordi forutsigbar argumentbehandling er det som gjør enheter reviderbare. Det overrasker bare dem som antar at det finnes et skall.

Skriv en enhet som sier nøyaktig hva som kjøres

Begynn med en liten enhet hvis formål er synlig i journalen, slik at parseproblemer holdes atskilt fra tunnelproblemer. Denne rapporterer bare versjonen til en binærfil.

[Unit]
Description=Report the installed OpenVPN version

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

Stien er en plassholder, så bytt den ut med binærfilen som faktisk er installert. Type=oneshot passer for en kommando som kjører til fullføring, og journalinnstillingene legger utdataene der du kan lese dem uten terminal. Det er bevisst ingen installasjonsseksjon, så enheten kalles opp for hånd i stedet for å aktiveres ved oppstart. Valider filen før du starter den, fordi en skrivefeil i et direktivnavn feiler annerledes enn en skrivefeil i stien.

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

Hold skallogikk i et skript

Når en hjelper virkelig trenger betinget logikk, legg den logikken i et skript og kall det eksplisitt. Skriptet trenger en tolklinje, kjøretillatelse og utgangskoder som tjenesten kan rapportere. Å starte /bin/sh -c med en kommando i anførselstegn virker, men det skjuler anførselstegnregler inne i en enhet og gjør gjennomgangen vanskeligere. Et navngitt skript kan testes for hånd og erstattes senere uten å redigere enheten. Ikke stol på skallprofilen til den interaktive brukeren, fordi en tjeneste starter med sitt eget miljø.

Sett WorkingDirectory når relative stier betyr noe, og send miljøet videre gjennom enhetens støttede direktiver i stedet for å eksportere det i en terminal. Hemmeligheter hører hjemme i beskyttede filer eller legitimasjon, ikke i argumentlister som journalen kan registrere.

Kontroller enheten som faktisk finnes

Drop-in-filer endrer atferd uten å røre filen du husker at du redigerte. Les hva behandleren lastet inn og hva den siste kjøringen rapporterte.

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

Enhetsutskriften inkluderer drop-in-filer i laste-rekkefølge, og det er vanligvis der en uventet ExecStart kommer fra. Etter enhver endring, last behandleren på nytt og bekreft at den nye definisjonen er det som systemctl cat skriver ut. Journalen viser den nøyaktige kommandolinjen og utgangsstatusen, noe som skiller et argumentproblem fra en manglende binærfil eller en tillatelsesfeil. Bestem deretter om hjelperen hører til den eksisterende VPN-livssyklusen eller bør forbli en manuell diagnose, fordi en andre bakgrunnstunnelprosess skaper en konkurrerende eier.

En enhet som skriver ut riktig utdata på forespørsel, er en god første milepæl. Den er ennå ikke en tunnel, og den bør ikke late som den er det.

Relaterte artikler