În mod surprinzător, după aproximativ 5 ani de WSL, nu pare să existe o întrebare „Systemd” bună, de uz general, aici pe Ask Ubuntu. Deci, acesta pare unul bun de folosit în acest scop.
Problema
În general, când vezi fie dintre următoarele două mesaje:
Sistemul nu a fost pornit cu systemd ca sistem init (PID 1). Nu pot opera.
Nu s-a putut conecta la autobuz: gazda este oprită
Atunci este de obicei aceeași cauză principală. În cazul în care systemctl
și încercând să pornească ssh
, le vezi pe amândouă.
Problema de bază, după cum se menționează în comentarii, este că WSL nu folosește Systemd, chiar și în distribuțiile în care este implicit. În schimb, WSL își folosește în prezent propriile sale /init
proces ca PID 1, care efectuează câteva sarcini specifice WSL pe care le menționez în acest raspuns (deci nu le voi repeta aici).
Și în timp ce WSL este (IMHO) o modalitate excelentă de a avea un CLI Linux complet în Windows (și recent, chiar și GUI), lipsa Systemd tinde să îngreuneze lucrurile în distribuțiile care aştepta sa fie acolo. Din fericire, Ubuntu este destul de bun în general în ceea ce privește capacitatea de a face față fără Systemd.
Cum să gestionați lipsa de Systemd
Și, indiferent, Systemd în esență este doar o „modalitate de a îndeplini sarcinile sistemului” (probabil o simplificare excesivă). Există (de obicei? întotdeauna?) o modalitate de a face aceeași sarcină fără Systemd și adesea mai multe moduri.
Opțiunea 1: „Modul vechi”
În Ubuntu pe WSL, multe dintre serviciile comune de sistem au încă „vechiul” init.d
scripturi disponibile pentru a fi utilizate în locul systemctl
cu unități Systemd. Acestea le puteți vedea folosind ls /etc/init.d/
.
Deci, de exemplu, puteți începe ssh
cu sudo service ssh start
, și va rula /etc/init.d/ssh
scenariu cu start
argument.
Chiar și unele pachete care nu sunt implicite, cum ar fi MySql/MariaDB, vor instala ambele fișiere de unitate Systemd și bătrânii init.d
scripturi, astfel încât să puteți utiliza în continuare serviciu
comanda si pentru ei.
Opțiunea 2: „Modul „manual””
Dar unele servicii nu au un echivalent init-script, mai ales pe alte distribuții. Pentru simplitate, să presupunem că ssh
init.d
scenariu nu a fost disponibil.
În acest caz, „răspunsul” este să vă dați seama ce fac fișierele unității Systemd și să încercați să replicați manual. Acest lucru poate varia foarte mult în complexitate. Dar aș începe cu privire la fișierul unității Systemd pe care încercați să îl rulați:
mai puțin /lib/systemd/system/ssh.service
# Decupat
[Serviciu]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
Am decupat unele dintre liniile mai puțin relevante pentru înțelegerea comportamentului său, dar puteți man systemd.exec
, man systemd.service
, și altele pentru a vedea ce fac majoritatea opțiunilor.
În acest caz, când tu sudo systemctl start ssh
, aceasta:
- Citește variabilele de mediu (
$SSHD_OPTS
) din /etc/default/ssh
- Testează configurația, iese dacă există o eroare
- Se asigură că RuntimeDirectory există cu permisiunile specificate. Aceasta se traduce prin
/run/sshd
(din man systemd.exec
). Acest lucru elimină, de asemenea, directorul de rulare atunci când opriți serviciul.
- Aleargă
/usr/sbin/sshd
cu optiuni
Deci, dacă nu aveți nicio configurație bazată pe mediu, puteți configura un script pentru:
- Asigurați-vă că directorul de rulare există. Rețineți că, deoarece este în
/alerga
, care este un tmpfs
mount, acesta va fi șters după fiecare repornire a instanței WSL.
- Setați permisiunile la
0755
- start
/usr/sbin/sshd
ca rădăcină
... Și tu ai fi făcut același lucru manual fără Systemd.
Din nou, acesta este probabil cel mai simplu exemplu. S-ar putea să aveți mult mai multe de lucrat pentru sarcini mai complexe.
Opțiunea 3: Rulați Systemd ca PID 1 într-un spațiu de nume/container PID
În sfârșit, este posibil pentru ca Systemd să ruleze sub WSL. Acesta este un subiect destul de avansat, deși există mai multe scripturi și proiecte care încearcă să-l simplifice. Chiar și așa, recomandarea mea personală este să te asigur că înțelegi ce se întâmplă în culise dacă folosești una dintre aceste tehnici.
Să începem cu unele dintre cele mai populare proiecte pentru a activa Systemd în WSL:
Personal nu am rulat niciunul dintre ele, dar toate sunt open-source și am scanat sursa pentru a compara tehnicile. În esență, fiecare creează un nou spațiu de nume sau container unde Systemd poate rula ca PID 1.
Puteți vedea acest lucru în acțiune urmând pașii:
Alerga:
sudo -b unshare --pid --fork --mount-proc /lib/systemd/systemd --system-unit=basic.target
Aceasta pornește Systemd într-un spațiu de nume nou cu propria sa mapare PID. În interiorul acelui spațiu de nume, Systemd va fi PID1 (așa cum trebuie, pentru a funcționa) și va deține toate celelalte procese. Cu toate acestea, maparea PID „reala” există încă în afara spațiului de nume.
Rețineți că aceasta este o linie de comandă „minimum” pentru pornirea Systemd. Nu va avea suport pentru, cel puțin:
- Windows Interop (abilitatea de a rula Windows
.executabil
)
- Windows PATH (care oricum nu este necesar fără Windows Interop)
Scripturile și proiectele enumerate mai sus fac muncă suplimentară pentru ca aceste lucruri să funcționeze, de asemenea.
Așteptați câteva secunde pentru ca Systemd să pornească, apoi:
sudo -E nsenter --all -t $(pgrep -xo systemd) runuser -P -l $USER -c "exec $SHELL"
Acesta intră în spațiul de nume și acum îl puteți utiliza ps -efH
pentru a vedea asta systemd
rulează ca PID 1 în acel spațiu de nume.
În acest moment, ar trebui să poți să alergi systemctl
.
Și după ce ți-ai dovedit că este posibil, recomand să ieși complet din instanța WSL, apoi să faci wsl --terminate <distro>
pe el. În caz contrar, unele lucruri vor fi „rupte” până când o vei face. Ele pot fi probabil „remediate”, dar asta depășește domeniul de aplicare al oricărei întrebări Ask Ubuntu ;-). Recomandarea mea este să vă referiți la proiectele de mai sus pentru a vedea cum se descurcă.