ExecStart ni lupina: popravljanje pomožne enote VPN
ExecStart zažene program z argumenti, ne cevovoda lupine. Uporabite izrecni tolmač ali pravo skripto, nato preverite enoto in preberite dnevnik.
Kopirajte delujočo ukazno vrstico v ExecStart, znova naložite in enota spodleti ali se tiho konča, ker se argumenti obravnavajo kot imena datotek. V systemd ni nič pokvarjeno. ExecStart je seznam argumentov, ne lupina, zato cevovodi, preusmeritve in pogoji izgubijo pomen v trenutku, ko zapustijo vaš terminal. Odločite, kam sodi lupina, in nato napišite enoto, ki natančno pove, kaj naj se izvede.
Zakaj cevovod v ExecStart ne naredi ničesar
Ko je ukaz vpisan v terminal, ga lupina najprej razčleni. Zgradi cevovod, odpre datoteke za preusmeritev in razširi spremenljivke, preden se zažene kateri koli program. systemd ne naredi nič od tega: razdeli ExecStart po svojih pravilih in izvede nastali program s temi argumenti. Zato > prispe kot dobesedni argument, | pa se preda programu, namesto da bi povezal dva procesa. Enota se ne obnaša narobe; sintaksa je pomenila nekaj drugega.
To je namerno in ne malomarno, ker predvidljivo ravnanje z argumenti dela enote pregledne. Preseneti le tiste, ki domnevajo, da je lupina prisotna.
Napišite enoto, ki natančno pove, kaj se izvaja
Začnite z majhno enoto, katere namen je viden v dnevniku, da težave z razčlenjevanjem ostanejo ločene od težav s tunelom. Ta poroča le različico binarne datoteke.
[Unit]
Description=Report the installed OpenVPN version
[Service]
Type=oneshot
ExecStart=/usr/sbin/openvpn --version
StandardOutput=journal
StandardError=journalPot je nadomestni znak, zato jo zamenjajte z binarno datoteko, ki je dejansko nameščena. Type=oneshot ustreza ukazu, ki teče do konca, nastavitve dnevnika pa njegov izhod postavijo tja, kjer ga lahko berete brez terminala. Razdelek za namestitev namerno manjka, zato se enota kliče ročno, namesto da bi se omogočila ob zagonu. Datoteko preverite pred zagonom, ker tipkarska napaka v imenu direktive spodleti drugače kot napaka na poti.
systemd-analyze verify /etc/systemd/system/openvpn-version.service
systemctl start openvpn-version.serviceLogiko lupine hranite v skripti
Ko pomočnik res potrebuje pogojno logiko, jo vstavite v skripto in jo izrecno pokličite. Skripta potrebuje vrstico tolmača, dovoljenje za izvajanje in izhodne kode, ki jih storitev lahko sporoči. Zaganjanje /bin/sh -c z ukazom v narekovajih deluje, a skrije pravila narekovajev znotraj enote in oteži pregled. Poimenovano skripto je mogoče ročno preizkusiti in pozneje zamenjati brez urejanja enote. Ne zanašajte se na profil lupine interaktivnega uporabnika, ker se storitev zažene z lastnim okoljem.
Nastavite WorkingDirectory, ko so pomembne relativne poti, in okolje posredujte prek podprtih direktiv enote, namesto da bi ga izvozili v terminalu. Skrivnosti spadajo v zaščitene datoteke ali poverilnice, ne v sezname argumentov, ki jih dnevnik lahko zabeleži.
Preverite enoto, ki v resnici obstaja
Datoteke drop-in spremenijo vedenje, ne da bi se dotaknile datoteke, za katero se spomnite, da ste jo urejali. Preberite, kaj je naložil upravljavec in kaj je sporočil zadnji zagon.
systemctl cat vpn-helper.service
journalctl -u vpn-helper.service -n 20 --no-pagerIzpis enote vključuje datoteke drop-in v vrstnem redu nalaganja in prav od tam običajno pride nepričakovan ExecStart. Po vsaki spremembi znova naložite upravljavca in potrdite, da je nova opredelitev tisto, kar izpisuje systemctl cat. Dnevnik prikaže natančno ukazno vrstico in izhodni status, kar loči težavo z argumenti od manjkajoče binarne datoteke ali napake z dovoljenji. Nato se odločite, ali pomočnik sodi v obstoječi življenjski cikel VPN ali mora ostati ročna diagnostika, ker drugi proces tunela v ozadju ustvari konkurenčnega lastnika.
Enota, ki na zahtevo izpiše pravi izhod, je dober prvi mejnik. Še ni tunel in se ne bi smela pretvarjati, da je.