Jak spustit linuxový program při spuštění s systemd

Potřebujete, aby se váš program v Linuxu automaticky spouštěl po startu systému? Systém systemd, který je dnes standardem ve většině linuxových distribucí včetně Ubuntu, vám to umožňuje. V tomto průvodci si ukážeme, jak vytvořit službu, která se integruje do systému a dokáže i zapisovat do logu.

Tento návod se zaměřuje na vytvoření systémové služby, která se spouští při startu systému. Pokud však potřebujete spouštět grafické aplikace po přihlášení uživatele, použijte správce automatického spouštění desktopového prostředí.

Automatické spouštění programů

Některý software se po instalaci automaticky začlení do spouštěcího procesu Linuxu, takže se program spustí pokaždé, když zapnete počítač. Stejného chování můžete dosáhnout u vašich vlastních skriptů a programů.

O spouštění programů při startu se stará systemd, správce systému a služeb. Systemd má při startu systému vždy proces ID 1. Každý další proces je spuštěn buď systemd, nebo jiným, již spuštěným procesem.

Programy běžící na pozadí se označují jako démoni nebo služby. Písmeno „d“ v názvu systemd odkazuje právě na slovo démon. V tomto článku vytvoříme ukázkovou službu, která splní následující požadavky:

  • Bude integrována se systemd pomocí souboru s definicí služby.
  • Bude spuštěna při startu systému.
  • Bude ji možné ovládat pomocí `systemctl`, nástroje pro správu systemd.
  • Bude umět zapisovat zprávy do logu.

Vytvoření skriptu pro službu

Nejprve potřebujeme program, který systemd spustí. Vytvoříme jednoduchý bash skript s názvem `htg.sh`. Používáme textový editor Gedit, ale můžete si vybrat jakýkoli jiný editor.

touch htg.sh
gedit htg.sh

Do editoru vložte tento kód:

#!/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

Uložte soubor a zavřete editor.

Tento skript sice nedělá nic složitého, ale obsahuje několik důležitých prvků:

  • Pomocí `systemd-cat` přesměrováváme výstup do logu. Zprávy mají prioritu „info“, což značí, že se jedná o informační hlášení, nikoliv o chybu nebo varování.
  • Skript obsahuje nekonečnou smyčku.
  • Proměnná `TIMESTAMP` uchovává aktuální datum a čas.
  • Skript zapisuje časové razítko do logu jednou za minutu a poté čeká 60 sekund.

Nyní zkopírujeme skript do adresáře `/usr/local/bin`:

sudo cp htg.sh /usr/local/bin

A nastavíme jej jako spustitelný:

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

Vytvoření souboru s definicí služby

Každá služba spouštěná systemd má svůj definiční soubor, který se nazývá soubor jednotky. Tento soubor obsahuje parametry pro spuštění a definuje chování služby.

Než vytvoříme náš soubor s definicí služby, zkontrolujeme, jestli název, který chceme použít, není již použit.

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

Vypíše se seznam všech existujících souborů jednotek. Zkontrolujeme, že se námi zamýšlený název nenachází v seznamu.

Naše služba se bude jmenovat `htg.service`. Vzhledem k tomu, že tento název není použit, můžeme pokračovat a vytvořit soubor jednotky.

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

Do editoru vložíme následující text:

[Unit]
Description=How-To Geek Service Example

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

Uložíme a zavřeme editor.

Následuje popis jednotlivých položek v souboru definice služby:

  • Description: Textový popis služby.
  • Wants: Určuje, že služba chce, aby síť byla dostupná, ale nevyžaduje to.
  • After: Seznam jednotek, které by se měly spustit až po této službě.
  • Type: Hodnota `simple` signalizuje systemd, že služba je spuštěna, jakmile se nastartuje proces specifikovaný v `ExecStart`.
  • ExecStart: Cesta ke spustitelnému souboru skriptu.
  • Restart: Určuje, kdy se má služba restartovat. V tomto případě je to „on-failure“, tedy při selhání.
  • RestartSec: Doba (v sekundách), po kterou se má čekat před opětovným pokusem o restart služby.
  • KillMode: Definice, jak má systemd ukončit proces, pokud požádáme o zastavení služby. Hodnota `process` zajistí, že systemd pošle signál SIGTERM pouze hlavnímu procesu. U komplexnějších programů bychom použili hodnotu `mixed`.
  • WantedBy: Definuje, kdy se má služba automaticky spouštět. Hodnota `multi-user.target` znamená, že se má spouštět, když je systém připraven pro přihlášení více uživatelů.

Samotný soubor jednotky nemusí být spustitelný, ale měli bychom omezit, kdo jej může upravovat. Dáváme právo čtení a zápisu vlastníkovi a čtení skupině:

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

Pomocí `systemctl` můžeme zkontrolovat syntaxi souboru jednotky, i když služba neběží:

systemctl status htg.service

Pokud nejsou zobrazeny žádné chyby, je soubor syntakticky v pořádku.

Spuštění služby

Při přidávání nového souboru jednotky, nebo při úpravě existujícího, je nutné znovu načíst definice souborů.

sudo systemctl daemon-reload

Pokud chceme, aby se služba spouštěla automaticky po startu systému, musíme ji povolit:

sudo systemctl enable htg

Povolení služby ji automaticky nespustí, pouze ji nastaví, aby se spouštěla po restartu počítače. Pokud chcete službu spustit okamžitě, použijte:

sudo systemctl start htg

Ověření funkčnosti služby

Po spuštění služby, buď manuálně, nebo po restartu počítače, můžeme ověřit, že funguje správně:

sudo systemctl status htg.service

Zobrazí se stav služby:

Zelená tečka signalizuje, že služba běží bez problému.

  • Název služby je `htg.service` a popisek je stejný, jako v definičním souboru.
  • Je zobrazen soubor jednotky: `/etc/systemd/system/htg.service`.
  • Služba je aktivní a je zobrazen i čas, od kdy je spuštěna.
  • PID procesu služby je 7762.
  • Se službou jsou spojené dva úkoly.
  • Služba používá 928 kibibajtů paměti.
  • Řídící skupina obsahuje skript `htg.sh` a příkaz `sleep`.

Zobrazí se posledních 10 záznamů z logu. Jak vidíme, zprávy se zapisují jednou za minutu.

Zastavení a deaktivace služby

Službu zastavíte příkazem:

sudo systemctl stop htg.service

Tímto se služba zastaví, ale při dalším restartu počítače se opět spustí. Pokud chcete, aby se služba nespouštěla po startu, musíte ji zakázat:

sudo systemctl disable htg.service

Tento příkaz službu nezastaví, pouze zajistí, že se nebude automaticky spouštět po startu systému.

Pro zastavení a zabránění automatického spuštění musíte použít oba příkazy.

Důležitá poznámka

Než se pokusíte spustit program jako službu, ujistěte se, že funguje podle vašich představ.