Jaki jest właściwy zamiennik rc.local w systemd zamiast ponownego tworzenia rc.local

25

Nie mogę znaleźć prawidłowego sposobu wykonywania niektórych skryptów lokalnych (lub bardzo lokalnych poleceń) w systemiedd, już wiem, że nie mogę tworzyć usługi (w jednostce systemd) dla tego rodzaju skryptów (czy muszę?) ....

Obejściem, które znalazłem, jest utworzenie pliku rc.local i nadanie mu uprawnień do wykonywania.

printf '#!/bin/bash \n\nexit 0' >/etc/rc.local 
chmod +x /etc/rc.local

Na przykład, jeśli otrzymam starszy serwer z skonfigurowanym przez Ciebie prostym plikiem rc.local, będę wiedział, co zrobiłeś i ile to zaszkodzi, aby zaktualizować lub zainstalować coś nowego w dystrybucji, ponieważ rc.local był przestrzegany przez zewnętrzny pakietów, ale z drugiej strony, jeśli zainstaluję serwer i utworzę jednostkę systemową lub dwie lub trzy (lub nawet usługi sysvinit), po prostu za wykonanie prostego zadania, może to czasem utrudnić ci życie, a nawet znacznie więcej nazwy mogą pewnego dnia kolidować z nazwami nowych usług tworzonych przez programistę dystrybucji, a być może instalowanych podczas aktualizacji, powodując problemy z moimi skryptami!

Widzę inne pytanie z pytaniem, gdzie jest rc.local, a odpowiedzią było, aby go utworzyć i dać uprawnienia do wykonywania, myślę, że moje pytanie tak naprawdę nie jest duplikatem , ponieważ nie chcę wiedzieć, gdzie to jest - uwierz mi, chcę tylko aby przyjąć , że jest przestarzałe , ale nie mogę znaleźć właściwą drogę do wykonywania tego rodzaju rzeczy, mam naprawdę stworzyć jednostkę tylko kilka prostych takiego?

Luciano Andress Martini
źródło
4
systemd „jedynym zwycięskim ruchem jest nie grać”; alternatywnie, w zależności od tego, co chcesz, możesz utworzyć jednostkę systemową. Prawdopodobnie użyłbym na razie rc.local i dbam o to, gdy zniknie.
Rui F Ribeiro
Więc uważasz, że oficjalnym sposobem jest stworzenie jednostki takiej jak usługa? Proszę wysłać jako odpowiedź, jak to zrobić.
Luciano Andress Martini
1
Kiedy wypróbowałem Ubuntu, stworzyłem Jednostkę do utrzymywania trwałego buforowania ssh-agent na moim pulpicie, podczas gdy nie uruchomiłem się ponownie, i inną dla czegoś innego, czego nie pamiętam; możesz także utworzyć taki, który wskazuje na /etc/rc.local, ale wygląda na to, że system robi to teraz na własną rękę ... Na razie zrobiłbym rc.local, a jeśli zostanie przerwany, utwórz taki, który wskazuje na fałszywy /etc/rc.local następnie.
Rui F Ribeiro
Może to zepsuć dokumentację, tak jakby jakaś książka mówiła, że ​​musisz coś umieścić w /etc/rc.local, i próbujesz zaktualizować te dokumenty, mówiąc na przykład, że rc.local musi być oznaczony jako wykonywalny, kiedy zostanie całkowicie przestarzały dokumentacja jest zepsuta, ale jeśli powiesz, że musisz utworzyć jednostkę, aby wskazywała /etc/rc.local, spowoduje to uszkodzenie dokumentacji, ponieważ systemd powoduje konflikt z twoją jednostką. Wierzę, że jeśli masz rację, prawdopodobnie nie zdecydowali, czy jest przestarzała, czy nie, ponieważ nadal nie mają substytutu ... kiedy zdecydują, że cała dokumentacja zostanie ponownie zepsuta.
Luciano Andress Martini
Jakiego rodzaju skrypt musisz wykonać? Systemd ma wiele typów jednostek. „Serwis” jest tylko jednym z wielu typów urządzeń . Np. Jednostki montażu, jednostki automount, jednostki timera, jednostki docelowe. Czy jeden z nich może rozwiązać Twój problem?
andcoz

Odpowiedzi:

17

Jak wskazano gdzie indziej, staje się nieczysty umiarkowanie używać rc-local.servicemocy systemd.

  1. Jest teoretycznie możliwe, że twoja dystrybucja go nie umożliwi. (Myślę, że nie jest to powszechne, np. Ponieważ wyłączenie tej samej opcji kompilacji usuwa również poweroff/ rebootpolecenia, z których korzysta wiele osób).
  2. Semantyka nie jest do końca jasna. Systemd określa rc-local.servicejeden sposób, ale Debian udostępnia plik rozwijany, który zmienia co najmniej jedno ważne ustawienie.

rc-local.serviceczęsto może dobrze działać. Jeśli martwisz się powyższym, wszystko, co musisz zrobić, to zrobić własną kopię! Oto magia:

# /etc/systemd/system/my-startup.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/libexec/my-startup-script

[Install]
WantedBy=multi-user.target

Nie sądzę, że musisz zrozumieć każdy szczegół [*], ale tutaj musisz wiedzieć dwie rzeczy.

  1. Musisz to włączyć za pomocą systemctl enable my-startup.service.

  2. Jeśli twój skrypt jest zależny od jakiejkolwiek innej usługi, w tym network-online.target, musisz ją zadeklarować. Np. Dodaj [Unit]sekcję z liniami Wants=network-online.targeti After=network-online.target.

    Nie musisz martwić się o zależności od usług „wczesnego rozruchu” - w szczególności usług już zamówionych wcześniej basic.target. Usługi takie my-startup.servicesą automatycznie zamawiane później basic.target, chyba że zostaną ustawione DefaultDependencies=no.

    Jeśli nie masz pewności, czy jedna z twoich zależności jest usługą „wczesnego rozruchu”, jednym z podejść jest wyświetlenie listy usług zamówionych wcześniej basic.target, poprzez uruchomienie systemctl list-dependencies --after basic.target. (Uwaga, że --afternie --before).

Są pewne uwagi, które moim zdaniem dotyczyły również systemu wstępnego rc.local:

  1. Musisz upewnić się, że twoje polecenia nie powodują konfliktu z innym programem, który próbuje kontrolować to samo.
  2. Najlepiej nie uruchamiać długo działających programów, czyli demonów rc.local.

[*] Użyłem Type=oneshot+, RemainAfterExit=yesponieważ ma to większy sens w przypadku większości skryptów jednorazowych. Formalizuje to, że uruchomisz serię poleceń, które my-startupzostaną wyświetlone jako „aktywne” po ich zakończeniu, i że nie uruchomisz demona.

sourcejedi
źródło
Cóż, istnieje jakieś „lokalne” miejsce do tworzenia usług lub fragmentów, czy cokolwiek innego - czy mogę ufać, że jest to miejsce lokalne i nie należy go zmieniać? jeśli opracuję własne demony? Ponieważ nie chcę zmieniać oryginalności systemu, więc kiedy instaluję apt-get, nie chcę, aby mój system był w ogniu z powodu zastąpionego skryptu lub czegoś takiego na przykład. Chcę tylko zaufać, że demon zostanie uruchomiony tylko raz, bez żadnych dodatkowych szalonych rzeczy, których się boję ... jak próba ponownego uruchomienia go jako nieskończoność, jeśli jest zepsuty itp.
Luciano Andress Martini,
1
@LucianoAndressMartini, jeśli pytasz, jaki jest właściwy sposób uruchomienia demona, powinieneś naprawdę zdefiniować dla niego indywidualną usługę. Może to być natywna .servicejednostka systemowa lub jeśli naprawdę chcesz napisać skrypt inicjujący LSB, możesz to zrobić zamiast tego. Nie chciałem zalecać umieszczania kilku demonów rc-local.servicelub równoważnych, myślę, że to prawdopodobnie działa, ale wydaje się o wiele przyjemniej, jeśli możesz zrestartować indywidualnego demona za pomocą systemctl restart my-daemonczegoś podobnego. Zamierzasz umieścić swoje lokalne usługi /etc/systemd/system.
sourcejedi
1
@LucianoAndressMartini musisz unikać używania tej samej nazwy jak w przypadku każdej innej usługi - tak jak w sysvinit. W podobnych sytuacjach czasami zaczynałem swoje imiona od local-...
sourcejedi
1
Dziękuję Ci!!! Zapisane po pół dnia. Te szczegóły były dla mnie kluczowe: Type = oneshot, RemainAfterExit = yes, Wants = network-online.target, After = network-online.target. Wystarczy wdrożyć kompilację Apache i ustawić statyczny adres IP na 192.168.1.80, aby router mógł kierować tam ruch. Powinien być trywialny. Jest to denerwujące w Debian9. Prawie żadna rada online z wyjątkiem „apt-get apache”, „systemctl start apache” lub instrukcji z init.d, z których żadna nie dotyczy wbudowanego Apache w systemie Debian9.
MichaelsonBritt
1
@MichaelsonBritt Najlepiej nie uruchamiać długo działających programów, czyli demonów z rc.local. Użyłem Type=oneshot... formalizuje to, że ... nie uruchomisz demona. Jeśli chcesz uzyskać informacje na temat uruchamiania demona, zadaj nowe pytanie.
sourcejedi
15

Zapomnij o rc.local.

Jak powiedziałem o CentOS 7 i Debianie 8 oraz Ubuntu 15 :

Używasz systemu systemd + Linux. /etc/rc.localjest podwójnym mechanizmem zgodności wstecznej w systemd, ponieważ jest to mechanizm zgodności wstecznej dla mechanizmu, który sam był mechanizmem zgodności w klonie van 5 Smoorenburga System rc.

Używanie /etc/rc.localmoże pójść okropnie źle. Ludzie byli zaskoczeni faktem, że systemd nie działa rc.localw taki sam sposób, w tym samym miejscu w bootstrapie, do którego są przyzwyczajeni. (Lub błędnie się spodziewałem: w rzeczywistości nie działał ostatni w starym systemie, jak wciąż wskazuje podręcznik OpenBSD.) Inni byli zaskoczeni faktem, że skonfigurowali się, rc.localoczekując starych sposobów robienia rzeczy, następnie całkowicie cofnięta przez m.in. nowych udevprzepisów, NetworkManager, systemd-logind, systemd-resolved, lub różne „zestaw” s.

Jak pokazano na przykładzie „ Dlaczego„ init 0 ”powoduje„ Nadmiar argumentów ”podczas instalacji Arch? ”, Niektóre systemy operacyjne już zapewniają systemd bez funkcji kompatybilności wstecznej, takich jak systemd-rc-local-generatorgenerator . Podczas gdy Debian nadal zachowuje funkcje kompatybilności wstecznej , Arch Linux buduje systemd z wyłączonymi . Tak więc w Arch i takich systemach operacyjnych oczekuje /etc/rc.local się całkowitego zignorowania .

Zapomnij o rc.local. To nie jest droga. Masz systemd + system operacyjny Linux. Stwórz więc odpowiednią usystematyzowaną jednostkę usługową i nie zaczynaj od punktu, który dzieli dwa poziomy kompatybilności wstecznej. (W Ubuntu i Fedorze jest trzy razy usuwany, rcklon van Smoorenburg System 5 , rc.localktóry następnie został dwukrotnie zastąpiony ponad dziesięć lat temu, najpierw przez start-up, a następnie przez systemd.)

Pamiętaj także o pierwszej regule migracji do systemd .

To nie jest nawet nowy pomysł, który jest specyficzny dla systemd. W systemach van Smoorenburg rci Upstart trzeba było zrobić odpowiedni rcskrypt van Smoorenburg lub plik zadania Upstart, a nie używać rc.local. Nawet podręcznik FreeBSD zauważa, że ​​w dzisiejszych czasach rczamiast korzystać z niego, tworzy się odpowiedni skrypt Mewburn /etc/rc.local. Mewburn rczostał wprowadzony przez NetBSD 1.5 w 2000 roku.

/etc/rc.localpochodzi z czasów wydania Siódmej Edycji Unix i wcześniejszych. Został on zastąpiony przez /etc/inittabATlev rci Unix System 3 oparty na poziomie pracy (nieco inny /etc/inittabw AT&T Unix System 5) w 1983 roku . Nawet to jest teraz historią.

Utwórz właściwe natywne definicje usług dla systemu zarządzania usługami, niezależnie od tego, czy będzie to pakiet usług dla zestawu narzędzi nosh service-manageri system-control, /etc/rc.d/skrypt dla Mewburn rc, plik jednostki usługi dla systemd, plik zadania dla Upstart, katalog usługi dla runit / s6 / daemontools -cencore, a nawet /etc/init.d/scenariusz do van Smoorenburga rc.

W systemie takie pliki dodane przez administratora są /etc/systemd/system/zwykle (lub /usr/local/lib/systemd/system/rzadko). Dzięki menadżerowi usług nosh, /var/local/sv/jest konwencjonalnym miejscem dla lokalnych pakietów usług. Używa Mewburn rcna FreeBSD /usr/local/etc/rc.d/. Pliki spakowanych jednostek usług i pakiety usług, jeśli je tworzysz, to jednak idź w różne miejsca.

Dalsza lektura

JdeBP
źródło
2
@LucianoAndressMartini Lepszym pytaniem byłoby, jak obsługiwać określony fragment pliku rc.local w usłudze systemowej. Więc jeśli masz na myśli konkretny fragment kodu (wspominasz instrukcje z dokumentacji oprogramowania), może zamiast tego opublikujesz pytanie na jego temat? Istnieją pewne ogólne zasady, których można użyć do konwersji, ale można z nich czerpać więcej, wykorzystując funkcje uruchomionego oprogramowania (takie jak uruchamianie na pierwszym planie, nie próby demonizacji itp.), Więc pytając o konkretny przypadek może być pomocny.
filbranden
4
Zastanawiasz się, czy przetrwała deprecjację od 1983 r., Może ma coś takiego?
Dan Carter
4
Ta odpowiedź jest głoszona i właściwie nie odpowiada tylko na proste pytanie „co trywialne powinienem zrobić zamiast tego”. Może zawierać informacje i dostarczać mnóstwo referencji, ale nie spełnia celu wymiany stosów.
gps
Mówię o tym (koniec rc.local), wraz z rozwiązywaniem problemów z dns, ponieważ powody, dla których Linux nie ewoluuje, ale w rzeczywistości staje się coraz bardziej kodem spaghetti, systemd stał się dla wielu czarną skrzynką. Jeśli użytkownik lub administrator chce umieścić coś w rc.local i nie może już tego zrobić, nie jest pomocne zmuszanie ich do najpierw robienia kursów systemowych lub cokolwiek innego, co głosisz, aby osiągnąć ten sam efekt końcowy w ciągu kilku dni, a nie minut. Oczywiście, idioci mogą robić głupie rzeczy ze wszystkim, co działa dobrze i jest łatwe w obsłudze, to nigdy nie jest prawidłowy argument, aby to zakończyć.
Julius
2

Podsumowanie https://www.linuxbabe.com/linux-server/how-to-enable-etcrc-local-with-systemd

Utwórz /etc/systemd/system/rc-local.service:

# /etc/systemd/system/rc-local.service
[Unit]
 Description=/etc/rc.local Compatibility
 ConditionPathExists=/etc/rc.local

[Service]
 Type=forking
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
 RemainAfterExit=yes
 SysVStartPriority=99

[Install]
 WantedBy=multi-user.target

Następnie:

sudo touch /etc/rc.local
sudo chmod +x /etc/rc.local
sudo systemctl enable rc-local

Sprawdź z:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
Ole Tange
źródło
Dostarczony przez systemd używa StandardOutput=journal+console(w twoim przykładzie konsola jest odpowiednikiem tty), co wydaje się bardziej przydatne w rozwiązywaniu problemów. W SysVStartPriority=pewnym momencie usunięto także obsługę dla . Może mógłbyś skomentować, jak ważne SysVStartPriority=jest, lub go usunąć. Poza tym jest to przyzwoita odpowiedź.
sourcejedi