Jak uruchomić program dla Linuksa przy starcie z systemd

Chciałbyś uruchomić aplikację Linux podczas uruchamiania systemu? Oprogramowanie systemd pozwala na to w większości dystrybucji Linuksa, w tym w Ubuntu. Poniżej przedstawimy ci krok po kroku, jak stworzyć zintegrowaną usługę, a także jak korzystać z dziennika systemowego.

W tym poradniku dowiesz się, jak skonfigurować usługę systemową, która uruchamia się automatycznie po starcie systemu. Jeśli chcesz uruchomić aplikację graficzną po zalogowaniu, lepiej skorzystaj z menedżera uruchamiania pulpitu.

Uruchamianie aplikacji podczas rozruchu

Czasami oprogramowanie instalowane na komputerze integruje się z procesem uruchamiania Linuksa, co pozwala na automatyczne uruchamianie programów przy każdym włączeniu komputera. Możesz uzyskać ten sam efekt dla własnych aplikacji, skryptów, czy dowolnego innego oprogramowania.

Uruchamiane podczas rozruchu programy są kontrolowane przez systemd, menedżera jednostek i usług. Systemd to pierwszy proces, który startuje podczas uruchamiania, zawsze z identyfikatorem procesu (PID) równym 1. Wszystkie inne procesy są uruchamiane przez systemd lub przez inne procesy, które zostały wcześniej uruchomione przez systemd.

Programy działające w tle są określane jako demonami lub usługami. Litera „d” w nazwie systemd pochodzi od terminu daemon. W tym artykule stworzymy przykładową usługę. Aby spełniała wymagania, nasza usługa musi być:

  • zintegrowana z systemd za pomocą pliku jednostki usługowej,
  • uruchamiana podczas startu,
  • zarządzana za pomocą systemctl, interfejsu sterującego dla systemd,
  • zdolna do zapisywania informacji w dzienniku.

Tworzenie skryptu usługi

Musimy przygotować skrypt, który będzie uruchamiany przez systemd. Stworzymy prosty skrypt o nazwie „htg.sh”. W tym przykładzie użyjemy edytora tekstu Gedit, ale możesz korzystać z dowolnego innego edytora, który preferujesz.

touch htg.sh
gedit htg.sh

Otworzy się edytor gedit. Skopiuj i wklej poniższy kod do edytora:

#!/bin/bash
echo "htg.service: ## Starting ##" | systemd-cat -p info
while :
do
    TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
    echo "htg.service: timestamp ${TIMESTAMP}" | systemd-cat -p info
    sleep 60
done

Zapisz zmiany i zamknij edytor.

Skrypt nie wykonuje skomplikowanych operacji, ale warto zwrócić uwagę na kilka kluczowych elementów:

  • Dwie linie wyjścia są przekazywane do systemd-cat, programu, który przesyła wyjście do dziennika. Wpisy mają przypisany priorytet, a my używamy opcji -p, aby określić, że nasze komunikaty są informacyjne.
  • W skrypcie znajduje się nieskończona pętla while.
  • Zmienna TIMESTAMP jest ustawiana na aktualną datę i godzinę, a następnie zapisywana w dzienniku.
  • Skrypt zasypia na 60 sekund przed powtórzeniem pętli, co oznacza, że co minutę zapisuje znacznik czasu w dzienniku.

Skopiujemy skrypt do katalogu /usr/local/bin.

sudo cp htg.sh /usr/local/bin

Następnie musimy nadać mu uprawnienia do wykonywania:

sudo chmod +x /usr/local/bin/htg.sh

Tworzenie pliku jednostki usługi

Każdy program uruchamiany przez systemd potrzebuje pliku definicyjnego, znanego jako plik jednostki usługi. Zawiera on atrybuty, które systemd może wykorzystać do lokalizacji, uruchomienia programu oraz zdefiniowania jego zachowania.

Musimy stworzyć plik jednostki dla naszej nowej usługi, ale warto upewnić się, że żaden z istniejących plików nie ma takiej samej nazwy.

sudo systemctl list-unit-files --type=service

Możesz przewijać listę plików, która jest posortowana alfabetycznie, aby sprawdzić, czy nazwa, którą chcesz użyć, jest już zajęta.

Nasza usługa będzie nosiła nazwę „htg.service”. Ponieważ żadna inna usługa nie ma tej nazwy, możemy przejść do tworzenia pliku jednostki.

sudo gedit /etc/systemd/system/htg.service

W edytorze gedit skopiuj i wklej poniższy tekst:

[Unit]
Description=Przykład usługi newsblog.pl

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/htg.sh
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

Zapisz zmiany i zamknij edytor.

Oto znaczenie poszczególnych wpisów. Choć nasza prosta usługa nie wymaga wielu z nich, ich uwzględnienie pozwala lepiej zrozumieć ich działanie:

  • Opis: tekstowy opis twojej usługi.
  • Wants: nasza usługa optymalnie wymaga działania sieci przed uruchomieniem.
  • After: lista jednostek, które powinny być uruchomione po pomyślnym uruchomieniu tej usługi.
  • Typ: prosty. Systemd uznaje tę usługę za uruchomioną, gdy tylko proces określony przez ExecStart zostanie rozpoczęty.
  • ExecStart: ścieżka do skryptu, który ma być uruchomiony.
  • Restart: określa, kiedy usługa powinna być ponownie uruchamiana. Ustawiliśmy to na „w przypadku awarii”.
  • RestartSec: czas oczekiwania przed próbą ponownego uruchomienia usługi (w sekundach).
  • KillMode: określa, w jaki sposób systemd powinien zakończyć proces, jeśli poprosimy systemctl o zatrzymanie usługi. Ustawiliśmy to na „przetwarzanie”, co oznacza, że systemd używa sygnału SIGTERM tylko dla głównego procesu.
  • WantedBy: ustawione na „multi-user.target”, co oznacza, że usługa powinna być uruchamiana, gdy system jest w stanie umożliwiającym logowanie wielu użytkowników, niezależnie od dostępności interfejsu graficznego.

Plik jednostkowy nie musi być wykonywalny, ale jego uprawnienia powinny ograniczać możliwość edytowania. Nie chcesz, aby złośliwy użytkownik mógł zmienić plik jednostki, by uruchamiał inny program.

Wykonaj poniższe polecenie, aby nadać właścicielowi uprawnienia do odczytu i zapisu oraz uprawnienia do odczytu grupie. Inni użytkownicy nie będą mieli dostępu.

sudo chmod 640 /etc/systemd/system/htg.service

Możemy sprawdzić składnię naszego pliku jednostkowego, nawet jeśli usługa nie jest jeszcze uruchomiona. Wszelkie błędy zostaną zgłoszone.

systemctl status htg.service

Brak błędów oznacza, że nasz plik jednostkowy jest poprawny pod względem składniowym.

Uruchamianie usługi

Gdy dodasz nowy plik jednostki lub edytujesz istniejący, musisz poinformować systemd o ponownym załadowaniu definicji plików jednostek.

sudo systemctl daemon-reload

Aby usługa była uruchamiana przy starcie, musisz ją włączyć:

sudo systemctl enable htg

Włączenie usługi nie uruchamia jej natychmiast, tylko ustawia, aby była uruchamiana podczas rozruchu. Aby teraz uruchomić usługę, użyj poniższego polecenia:

sudo systemctl start htg

Weryfikacja działania usługi

Po ręcznym uruchomieniu usługi lub po ponownym uruchomieniu systemu, możesz sprawdzić, czy usługa działa poprawnie.

sudo systemctl status htg.service

Status usługi zostanie wyświetlony.

Zielona kropka oznacza, że usługa działa poprawnie. Nazwa usługi to „htg.service”, a długi opis pochodzi z pliku jednostki. Zobaczysz również, jaki plik jednostki został załadowany „/etc/systemd/system/htg.service”. Usługa jest aktywna, a czas jej uruchomienia oraz PID są widoczne. W przypadku tej usługi używanych jest 928 Kibibajtów pamięci. Grupa kontrolna zawiera skrypt „htg.sh” oraz polecenie sleep, które zostało uruchomione przez „htg.sh”. W większości sytuacji to polecenie sleep będzie pełniło rolę usługi.

Możesz również zobaczyć 10 ostatnich wpisów w dzienniku utworzonych przez tę usługę, które są oddalone od siebie o minutę.

Zatrzymywanie i wyłączanie usługi

Aby zatrzymać usługę, użyj następującego polecenia:

sudo systemctl stop htg.service

To polecenie zatrzyma usługę, ale nie wyłączy jej z autostartu przy następnym uruchomieniu. Aby zablokować uruchamianie usługi podczas rozruchu, użyj:

sudo systemctl disable htg.service

Jeśli usługa jest uruchomiona, to polecenie jej nie zatrzyma. Informuje tylko systemd, aby nie uruchamiać usługi przy następnym rozruchu.

Aby zatrzymać usługę i zapobiec jej uruchamianiu podczas rozruchu, wykonaj oba polecenia.

Porada dotycząca usług

Upewnij się, że program działa zgodnie z oczekiwaniami, zanim spróbujesz uruchomić go jako usługę.