Nejjednodušším způsobem, jak spustit z povelové řádky úlohu na pozadí, je využítí úloh (jobs) v shellu. I když úlohy na pozadí podporují i jiné shelly, zde si popíšeme pouze nejpoužívanější linuxový shell - bash.
Úlohu odešleme na pozadí kombinací kláves CTRL-Z. Úloha odeslaná na pozadí tímto způsobem je pozastavená, takže chceme-li ji pustit, musíme použít příkaz bg.
$ sleep 100 ^Z [1]+ Pozastaven sleep 100 $ bg [1]+ sleep 100 & $ [1]+ Dokonán sleep 100
Mimo příkaz bg, kterým spustíme úlohu pozastavenou na pozadí, můžeme svůj spuštěný program příkazem fg z pozadí vylovit a poslat opět na povelovou řádku, do popředí:
$ sleep 100 ^Z $ fg sleep 100 $
Úlohu lze odeslat na pozadí i přímo, bez nutnosti mačkat kombinaci CTRL-Z, uvedením znaku & (ampersand) na konci řádku s příkazem. S takto spuštěnou úlohou lze pracovat pomocí příkazů fg, bg a CTRL-Z, jak jsme si popsali v odstavcích výše:
$ sleep 100 [1] 26579 $ fg sleep 100 ^Z [1]+ Pozastaven sleep 100 $ bg [1]+ sleep 100 & $ [1]+ Dokonán sleep 100
Úloh lze na pozadí spustit libovolné množství. Protože už dvě úlohy jsou dost na to, aby uživatel ztratil o úlohách na pozadí přehled, nabízí shell příkaz jobs. Tímto příkazem vypíšete všechny úlohy na pozadí:
$ sleep 100 & [1] 26804 $ sleep 200 & [2] 26806 $ jobs [1]- Běží sleep 100 & [2]+ Běží sleep 200 &
Povšimněte si čísla v hranaté závorce na začátku řádku - jde o číslo úlohy v shellu (liší se od PID, čísla procesu v systému, zde 26804 a 26806). Číslo úlohy v shellu usnadňuje práci s úlohami na pozadí pomocí příkazů fg, bg a kill. U těchto tří příkazů lze uvést jako parametr číslo úlohy uvezené znakem % (procento):
$ sleep 100 & [1] 26924 $ sleep 200 & [2] 26926 $ fg %1 sleep 100 ^Z [1]+ Pozastaven sleep 100 $ kill %1 [1]- Ukončen (SIGTERM) sleep 100
U výpisu spuštěných úloh si můžete povšimnout znaků + (plus) a - (minus):
[2] Běží sleep 100 & [3]- Běží sleep 200 & [4]+ Běží sleep 300 &
Aktuální úloha je označená znakem + (plus). Příkazy fg a bg použité bez parametrů budou pracovat právě s touto úlohou. Pro úlohy lze použít i identifikátory %% (aktuální úloha) %+ (aktuální úloha) a %- (předchozí úloha):
kill %% [4]+ Ukončen (SIGTERM) sleep 300
Spustíte-li na pozadí podle předchozí části článku například překlad rozsáhlého projektu a odhlásíte se, po návratu k počítači budete nepříjemně překvapení - vaše úlohy na pozadí byly ukončené signálem SIGHUP zároveň s odhlášením (ukončením shellu). Abyste se této situaci vyhnuli, můžete použít příkaz nohup. Sám od sebe tento příkaz nespouští úlohy na pozadí, musíte uvést znak & za příkazem nebo použít kombinaci CTRL-Z a úlohu na pozadí rozběhnout příkazem bg:
$ nohup sleep 200 & [1] 27701 nohup: vstup ignoruji a výstup připojuji k „nohup.out“ $ # po odhlášení a přihlášení: $ ps xa | grep sleep 28045 ? S 0:00 sleep 100
Příkaz nohup přesměruje standardní výstup a standardní chybový výstup programu do souboru nohup.out v aktuálním adresáři. Nelze-li do aktuálního adresáře zapisovat, pokusí se nohup vytvořit soubor nohup.out v domácím adresáři uživatele. Nepodaří-li se vytvořit ani zde, nebude příkaz proveden.
Spuštění úlohy na pozadí tak, aby přežila i odhlášení, lze dosáhnout i příkazem disown. Chování tohoto příkazu se však od příkazu nohup liší. Příkaz nohup odchytí signál SIGHUP odesílaný shellem a přesměruje výstup programu. Příkazem disown naproti tomu informujete shell, že uvedenemu programu se nemá při ukončení shellu signál SIGHUP posílat. O výstupy programu při odhlášení příjdete. Na druhou stranu lze příkazem disown odeslat na pozadí i program, u kterého jsme to předem neplánovali. Jako parametr lze příkazu disown poslat UID procesu, případně číslo úlohy v shellu (uvozené procentem):
$ sleep 100 & [1] 28150 $ disown %1 # po odhlášení a přihlášení: $ ps xa | grep sleep 28150 ? S 0:00 sleep 100
Všechny výše uvedené způsoby spouštění úloh na pozadí mají několik nevýhod. Zásadní nevýhodou je, že výstup z programu je neustále přesměrovaný na výstup. Pustíte-li si na pozadí překlad většího projektu, je použitá povelová řádka pro další interaktivní práci prakticky nepoužitelná, protože se vám na ni bude vypisovat průběh překladu. Můžete sice použít příkaz nohup a výstup přesměrovat do souboru, ale takto zase přijdete o možnost překlad dále jakkoliv ovlivnit (vstup se ignoruje). Pro úlohy, které jsou alespoń částečně interaktivní, postrádá výše popsaný způsob spouštění na pozadí přijatelný komfort.
Omezení a nevýhody uvedených postupů odstraňuje příkaz screen. Správa úloh v programu screen je zcela odlišná od úloh v shellu. Program screen vytváří několik instancí shellu (a obrazovek), mezi kterými lze libovolně přepínat. V každém shellu lze samozřejmě spouštět další úlohy na pozadí s použitím shellu. Nastartoval lze i další screen, ale vhodnější je vytvoření další obrazovky.
$ screen $ sleep 100 ^AD [detached] $ screen -r $ sleep 100
Příkaz screen se ovládá pomocí přepínačů a zkratek. Pro nejjednodušší použítí stačí znát jen několik základních postupů:
screen | Vytvoření nové nezávislé obrazovky. |
CTRL-A D | Odpojení od obrazovky |
CTRL-A C | Vytvoření nové obrazovky v nastartovaném programu screen (musíte být připojení) |
CTRL-A N | Přepnutí na další obrazovku v pořadí |
CTRL-A P | Přepnutí na předchozí obrazovku v pořadí |
CTRL-D | Ukončení aktuální obrazovky. Ve skutečnosti jde o příkaz shellu, obrazovka se ukončí, jakmile je ukončen program v ní spuštěný (obvykle právě shell). |
screen -r | Připojení ke screenu. Zde může běžet libovolný počet obrazovek. |
screen -r 12345 | Připojení ke screenu s uvedeným PID. Screenů můžete mít nastartovaných více. |
screen -D -R | Připojení ke screenu a to i v případě, že je screen připojený už někam jinam (druhá obrazovka se odpojí). Užitečné, pokud v práci spustíte překlad, zapomenete se odpojit, a doma se chcete podívat na průběh překladu. |
screen -wipe | Vyčištění seznam screenů od nefunkčních instancí. |
Možnosti programu screen jsou mnohem širší. Podrobnosti najdete v manuálové stránce.