Jak používat at a dávkovat v Linuxu k plánování příkazů

Jestliže potřebujete v Linuxu naplánovat jednorázovou úlohu, cron je zbytečně složitý. V takovém případě se nabízí využít nástroje z rodiny příkazů at. Pokud byste pak chtěli procesy spouštět pouze tehdy, když váš systém nemá velké zatížení, můžete sáhnout po batch.

Plánování úloh v Linuxu s využitím at

Démon cron spravuje seznam úkolů, které automaticky spouští v definovaných časech. Tyto úlohy a programy běží na pozadí v naplánovaných intervalech, což nabízí velkou flexibilitu pro plánování opakujících se akcí. Cron je ideální pro úlohy, které je potřeba spouštět pravidelně – ať už jde o každou hodinu, denně v určitou dobu, nebo třeba jednou za měsíc či rok.

Nicméně, v situaci, kdy potřebujete spustit úlohu pouze jednou, cron není ideální. Sice by se to s cronem dalo zařídit, ale museli byste následně odstranit záznam z crontabu po dokončení úlohy, což je nepraktické.

S velkou pravděpodobností se s problémem, na který narazíte v Linuxu, již setkal někdo jiný. A díky tomu, že systémy podobné Unixu jsou s námi tak dlouho, je velká šance, že existuje řešení i pro vaši situaci.

Pro výše zmíněný problém, kdy potřebujete jednorázově naplánovat úlohu, se nabízí právě příkaz at.

Instalace příkazu at

Příkaz at jsme museli instalovat na Ubuntu 18.04 a Manjaro 18.1.0, zatímco na Fedoře 31 byl již předinstalován.

Pro instalaci na Ubuntu použijte následující příkaz:

sudo apt-get install at

Po dokončení instalace spusťte démona at pomocí tohoto příkazu:

sudo systemctl enable --now atd.service

Na Manjaru provedete instalaci následujícím příkazem:

sudo pacman -Sy at

Po úspěšné instalaci aktivujte démona at použitím následujícího příkazu:

sudo systemctl enable --now atd.service

V jakékoliv distribuci můžete ověřit, že démon atd běží pomocí tohoto příkazu:

ps -e | grep atd

Interaktivní použití příkazu at

Pro použití příkazu at musíte zadat datum a čas, kdy má být úloha spuštěna. Způsoby, jakými můžete zadávat čas, jsou velmi flexibilní, což si ukážeme dále v tomto textu.

I když používáte příkaz at interaktivně, musíte předem specifikovat datum a čas. Pokud do příkazového řádku nezadáte žádný čas nebo zadáte něco, co se nedá interpretovat jako čas, dostanete odpověď „špatný čas“, jak je vidět níže:

at
at banana

Data a časy mohou být zadávány explicitně nebo relativně. Například, pokud chcete, aby se příkaz spustil za minutu, at chápe pojem „teď“, takže můžete použít klíčové slovo now a přidat k němu jednu minutu, takto:

at now + 1 minute

at vypíše zprávu a výzvu at>, kde očekává, že zadáte příkazy, které chcete naplánovat. Nejprve si ale všimněte zprávy, která se zobrazí, jak je uvedeno níže:

Zpráva uvádí, že instance shellu sh bude spuštěna a provede se v ní sada příkazů. Vaše příkazy se tedy nespustí v prostředí Bash, ale v shellu sh, který je sice s Bashem kompatibilní, ale má chudší sadu funkcí.

Pokud vaše příkazy nebo skripty budou využívat funkce specifické pro Bash, které nejsou dostupné v shellu sh, akce selže.

Pro ověření, zda vaše příkazy a skripty fungují správně v shellu sh, použijte příkaz sh, který spustí shell sh:

sh

Příkazový řádek se změní na znak dolaru ($) a nyní můžete ověřit, zda vaše příkazy fungují správně.

Pro návrat do prostředí Bash použijte příkaz exit:

exit

Nebudete vidět žádný standardní výstup nebo chybové zprávy od příkazů. Důvodem je, že shell sh běží jako úloha na pozadí a nemá žádné rozhraní s obrazovkou.

Jakýkoli výstup z příkazů – ať už úspěšný, nebo chybový – vám bude zaslán e-mailem. E-mail se odesílá prostřednictvím interního poštovního systému tomu uživateli, který příkaz at zadal. Je tedy potřeba mít nastavený a nakonfigurovaný tento interní e-mailový systém.

V mnoha (většině) linuxových systémech není interní e-mailový systém aktivní, protože se používá jen zřídka. Pokud již nějaký interní poštovní systém používají, jedná se obvykle o systémy jako sendmail nebo postfix. Pokud váš systém interní e-mailový systém nemá, můžete nechat skripty zapisovat do souborů nebo přesměrovávat jejich výstup do souborů pro logování.

Pokud příkaz nevygeneruje žádný standardní výstup nebo chybové zprávy, e-mail neobdržíte. Mnoho linuxových příkazů signalizuje úspěch tím, že nehlásí žádnou chybu, takže ve většině případů se vám žádný e-mail neobjeví.

Nyní je čas zadat příkaz. V tomto příkladu použijeme malý skript s názvem sweep.sh, který odstraňuje soubory s příponami *.bak, *.tmp a *.o. Zadejte cestu k příkazu, jak je znázorněno níže, a stiskněte klávesu Enter.

Zobrazí se další příkazový řádek, a můžete zadat libovolný počet příkazů. Nicméně, pro lepší přehlednost je většinou výhodnější mít všechny příkazy v jednom skriptu, a ten z příkazu at pouze zavolat.

Stisknutím Ctrl+D dáte vědět, že jste dokončili zadávání příkazů. Zobrazí se <EOT>, což je zkratka pro konec přenosu. Poté se vám zobrazí číslo úlohy a čas, kdy má být spuštěna, jak je uvedeno níže:

Po provedení úlohy zadejte pro kontrolu interní pošty:

mail

Pokud žádná pošta není, předpokládejte, že se úloha provedla v pořádku. V tomto případě můžete samozřejmě zkontrolovat, zda se soubory *.bak, *.tmp a *.o smazaly, abyste se ujistili, že příkaz fungoval.

Chcete-li provést celou akci ještě jednou, zadejte:

at now + 1 minute

Po jedné minutě zadejte následující příkaz a zkontrolujte poštu znovu:

mail

Výborně, máme novou poštu! Pro přečtení zprávy číslo jedna stiskněte 1 a poté Enter.

Obdrželi jsme e-mail od na, protože příkazy ve skriptu vygenerovaly chybové zprávy. V tomto příkladu nebyly žádné soubory ke smazání, protože skript jsme už jednou spustili, a ty soubory smazal.

Stiskněte D+Enter pro smazání e-mailu a Q+Enter pro ukončení poštovního programu.

Formáty zadávání data a času

Máte velkou flexibilitu v tom, jaké formáty času můžete použít. Zde je několik příkladů:

Spuštění v 11:00:

at 11:00 AM

Spuštění zítra v 11:00:

at 11:00 AM tomorrow

Spuštění příští týden ve stejný den v 11:00:

at 11:00 AM next week

Spuštění v tento čas, tento den příští týden:

at next week

Spuštění příští pátek v 11:00:

at 11:00 AM next fri

Spuštění příští pátek v tento čas:

at next fri

Spuštění v 11:00 v tento den, příští měsíc:

at 11:00 AM next month

Spuštění v 11:00 v konkrétní den:

at 11:00 AM 3/15/2020

Spuštění za 30 minut od teď:

at now + 30 minutes

Spuštění za dvě hodiny:

at now + 2 hours

Spuštění zítra v tento čas:

at tomorrow

Spuštění ve čtvrtek v tento čas:

at thursday

Spuštění o půlnoci:

at midnight

Spuštění v poledne:

at noon

Pokud jste Brit, můžete si dokonce naplánovat spuštění příkazu v době čaje (16:00):

at teatime

Zobrazení fronty úloh

Pro zobrazení fronty naplánovaných úloh použijte příkaz atq, jak je uvedeno níže.

Pro každou úlohu ve frontě atq zobrazí následující informace:

  • ID úlohy
  • Plánované datum
  • Plánovaný čas
  • Frontu, ve které se úloha nachází. Fronty se označují „a“, „b“ atd. Normální úlohy, které naplánujete pomocí at, jsou ve frontě „a“, zatímco úlohy naplánované pomocí příkazu batch (popsaného dále) jsou ve frontě „b“.
  • Osoba, která úlohu naplánovala.

Použití at z příkazové řádky

Příkaz at nemusíte používat jen interaktivně; můžete ho také použít v příkazech, což usnadňuje jeho využití ve skriptech.

Příkazy můžete zadat pro at takto:

echo "sh ~/sweep.sh" | at 08:45 AM

Úloha je přijata a naplánována. Číslo úlohy a datum spuštění se zobrazí stejně jako dříve.

Použití at se soubory příkazů

Můžete také uložit posloupnost příkazů do souboru a předat ho příkazu at. Může to být prostý textový soubor s příkazy – nemusí to být spustitelný skript.

Pro předání názvu souboru příkazu at můžete použít volbu -f (file) takto:

at now + 5 minutes -f clean.txt

Stejného výsledku můžete dosáhnout, pokud soubor přesměrujete do at:

at now + 5 minutes < clean.txt

Odstraňování naplánovaných úloh z fronty

Pro odstranění naplánované úlohy z fronty můžete použít příkaz atrm. Pokud chcete nejprve zjistit číslo úlohy, kterou chcete odstranit, použijte příkaz atq. Potom použijte toto číslo úlohy s příkazem atrm, jak je uvedeno níže:

atq
atrm 11
atq

Jak zobrazit podrobný pohled na úlohy

Jak již bylo zmíněno, úlohy je možné plánovat i s velkým předstihem. Někdy se vám může stát, že zapomenete, co má která úloha dělat. Příkaz atq vám sice ukáže úlohy ve frontě, ale neřekne, co vlastně dělají. Pokud potřebujete detailní pohled na konkrétní úlohu, použijte volbu -c (cat).

Nejprve pomocí atq najdeme číslo úlohy:

atq

Nyní použijeme úlohu číslo 13 s volbou -c:

at -c 13

Zde je rozpis informací, které o úloze získáte:

  • První řádek: říká nám, že příkazy poběží v shellu sh.
  • Druhý řádek: vidíme, že příkazy budou spuštěny s ID uživatele a skupiny 1000. To jsou hodnoty pro uživatele, který spustil příkaz at.
  • Třetí řádek: uživatel, který obdrží případné e-maily.
  • Čtvrtý řádek: uživatelská maska je 22. To je maska používaná k nastavení výchozích oprávnění pro soubory vytvořené v této relaci shellu sh. Maska se odečítá od 666, což nám dává 644 (oktalový ekvivalent rw-r--r--).
  • Zbývající data: většinou proměnné prostředí.

  • Výsledky testu. Test kontroluje, zda je možné přistupovat ke spouštěcímu adresáři. Pokud ne, dojde k chybě a provedení úlohy se ukončí.
  • Příkazy, které se mají provést. Ty se vypíší a zobrazí se obsah skriptů, které jsou naplánované. Všimněte si, že i když byl skript v našem příkladu napsán tak, aby se spouštěl v Bash, bude spuštěn v shellu sh.

Příkaz batch

Příkaz batch funguje podobně jako příkaz at, ale s třemi zásadními rozdíly:

  • Příkaz batch můžete použít pouze interaktivně.
  • Namísto plánování úloh pro konkrétní čas, jsou úlohy přidávány do fronty a příkaz batch je provede, když průměrné zatížení systému klesne pod hodnotu 1.5.
  • Z výše uvedeného plyne, že u příkazu batch nikdy neurčujete konkrétní datum a čas spuštění.

Při použití příkazu batch ho zavoláte bez parametrů, například takto:

batch

Poté přidejte úlohy stejným způsobem jako u příkazu at.

Řízení přístupu k příkazu at

Soubory at.allow a at.deny řídí, kdo může používat příkazy z rodiny at. Tyto soubory se nacházejí v adresáři /etc. Ve výchozím stavu existuje pouze soubor at.deny, který se vytvoří při instalaci at.

Funguje to následovně:

  • at.deny: obsahuje aplikace a uživatele, kterým není povolené plánovat úlohy.
  • at.allow: obsahuje uživatele, kteří mohou plánovat úlohy pomocí at. Pokud soubor at.allow neexistuje, at používá pouze soubor at.deny.

Ve výchozím stavu může příkaz at používat kdokoliv. Chcete-li omezit, kdo ho může používat, použijte soubor at.allow, do kterého vypište uživatele, kteří mohou příkaz at používat. Je to jednodušší, než přidávat do souboru at.deny všechny uživatele, kteří příkaz používat nemohou.

Zde je obsah souboru at.deny:

sudo less /etc/at.deny

Soubor obsahuje seznam součástí operačního systému, které nemohou používat příkaz at. Mnohé z nich mají zabráněn přístup z bezpečnostních důvodů, a proto byste z tohoto souboru neměli nic odstraňovat.

Nyní upravíme soubor at.allow. Přidáme uživatele dave a mary, a nikdo jiný nebude moci at používat.

Nejprve zadejte:

sudo gedit /etc/at.allow

V editoru přidáme dva uživatele, jak je uvedeno níže, a soubor uložíme.

Pokud se někdo jiný pokusí at použít, bude mu sděleno, že k tomu nemá oprávnění. Například, pokud uživatel jménem eric zadá následující příkaz:

at

Bude odmítnut, jak je vidět níže.

Je potřeba znovu zdůraznit, že uživatel eric není v souboru at.deny. Jakmile vložíte kohokoli do souboru at.allow, budou mít všichni ostatní zakázané oprávnění k používání příkazu at.

Skvělé pro jednorázové úlohy

Jak vidíte, at i batch jsou ideální pro úlohy, které potřebujete spustit pouze jednou. Rychlé shrnutí:

  • Pokud potřebujete provést něco, co není běžná operace, naplánujte si to pomocí at.
  • Pokud chcete spustit úlohu jen tehdy, když je zatížení systému dostatečně nízké, použijte batch.