Kopioi toimiva komentorivi ExecStartiin, lataa uudelleen, ja yksikkö epäonnistuu tai päättyy äänettömästi, koska argumentit tulkitaan tiedostonimiksi. systemd:ssä ei ole mitään rikki. ExecStart on argumenttiluettelo, ei shell, joten putket, uudelleenohjaus ja ehdot menettävät merkityksensä heti, kun ne poistuvat päätteeltäsi. Päätä, mihin shell kuuluu, ja kirjoita sitten yksikkö, joka kertoo täsmälleen, mitä pitää suorittaa.

Miksi ExecStartin putki ei tee mitään

Kun komento kirjoitetaan päätteelle, shell jäsentää sen ensin. Se rakentaa putken, avaa tiedostoja uudelleenohjausta varten ja laajentaa muuttujat ennen kuin mikään ohjelma käynnistyy. systemd ei tee mitään tästä: se jakaa ExecStartin omien sääntöjensä mukaan ja suorittaa tuloksena olevan ohjelman näillä argumenteilla. Siksi > saapuu kirjaimellisena argumenttina ja | annetaan ohjelmalle sen sijaan, että se yhdistäisi kaksi prosessia. Yksikkö ei käyttäydy väärin; syntaksi tarkoitti jotain muuta.

Se on tahallista eikä huolimatonta, koska ennustettava argumenttien käsittely tekee yksiköistä auditoitavia. Se yllättää vain ne, jotka olettavat shellin olevan läsnä.

Kirjoita yksikkö, joka kertoo täsmälleen, mitä ajetaan

Aloita pienestä yksiköstä, jonka tarkoitus näkyy journalissa, jotta jäsennysongelmat pysyvät erillään tunneliongelmista. Tämä ilmoittaa vain binäärin version.

[Unit]
Description=Report the installed OpenVPN version

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

Polku on paikkamerkki, joten korvaa se binäärillä, joka on todella asennettu. Type=oneshot sopii komennolle, joka ajetaan loppuun asti, ja journalin asetukset vievät sen tulosteen sinne, missä voit lukea sen ilman päätettä. Asennusosiota ei ole tarkoituksella, joten yksikkö kutsutaan käsin sen sijaan, että se otettaisiin käyttöön käynnistyksessä. Validoi tiedosto ennen sen käynnistämistä, koska kirjoitusvirhe direktiivin nimessä epäonnistuu eri tavalla kuin virhe polussa.

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

Pidä shell-logiikka skriptissä

Kun apuri todella tarvitsee ehdollista logiikkaa, laita se logiikka skriptiin ja kutsu sitä nimenomaisesti. Skripti tarvitsee tulkkirivin, suoritusoikeuden ja poistumiskoodit, jotka palvelu voi ilmoittaa. Käynnistäminen /bin/sh -c lainatulla komennolla toimii, mutta se kätkee lainausmerkkisäännöt yksikön sisään ja vaikeuttaa tarkistusta. Nimetty skripti voidaan testata käsin ja korvata myöhemmin muokkaamatta yksikköä. Älä luota interaktiivisen käyttäjän shell-profiiliin, koska palvelu käynnistyy omassa ympäristössään.

Aseta WorkingDirectory, kun suhteelliset polut ovat tärkeitä, ja välitä ympäristö yksikön tuettujen direktiivien kautta sen sijaan, että veisit sen päätteellä. Salaisuudet kuuluvat suojattuihin tiedostoihin tai tunnistetietoihin, eivät argumenttiluetteloihin, jotka journal voi tallentaa.

Tarkista yksikkö, joka todella on olemassa

Drop-in-tiedostot muuttavat käyttäytymistä koskematta tiedostoon, jonka muistat muokanneesi. Lue, mitä hallinta latasi ja mitä viimeisin ajo ilmoitti.

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

Yksikön tuloste sisältää drop-in-tiedostot latausjärjestyksessä, ja juuri sieltä odottamaton ExecStart yleensä tulee. Lataa hallinta uudelleen jokaisen muutoksen jälkeen ja varmista, että uusi määritelmä on se, mitä tulostaa systemctl cat. Journal näyttää tarkan komentorivin ja poistumistilan, mikä erottaa argumenttiongelman puuttuvasta binääristä tai käyttöoikeusvirheestä. Päätä sitten, kuuluuko apuri olemassa olevaan VPN-elinkaareen vai pitäisikö sen jäädä manuaaliseksi diagnostiikaksi, koska toinen taustalla oleva tunneliprosessi luo kilpailevan omistajan.

Yksikkö, joka tulostaa oikean tulosteen pyydettäessä, on hyvä ensimmäinen virstanpylväs. Se ei ole vielä tunneli, eikä sen pidä teeskennellä olevansa.

Aiheeseen liittyvät artikkelit