Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Software
Časované úlohy, díl druhý
25. května 2006, 00.00 | Minule jsme si nastínili možnosti, jak v některých případech šetřit náš čas svěřením často opakovaných úkonů počítači. Ukázkové aplikace máte již jistě hotové a vyzkoušené. Nyní si tedy ukážeme, jak plně automatické úlohy vytvářet a spravovat.
Systém nám nabízí více možností, mimo standardních příkazů systémů Unix (například cron) máme v Mac OS X od verze 10.4 k dispozici z uživatelského hlediska přístupnější formu – rozhraní launchd, které se stará o automatické spouštění dalších programů, především v souvislosti se serverovými službami a poskytuje prostředky pro jejich následnou správu. Více informací o launchd získáte zadáním příkazů man launchd a man launchctl v terminálu.
Možnosti launchd jsou rozsáhlé, v našem článku se v zájmu zachování maximální přehlednosti a srozumitelnosti omezíme jen na jeden příklad – spouštění "běžného" programu v časovém intervalu. Začneme tím, že vytvoříme tzv. "spouštěcího agenta" (Launch Agent), který bude prostředníkem mezi rozhraním launchd a naším programem. V praxi jde vlastně pouze o konfigurační soubor ve formátu XML, který předá údaje o tom, co se má kdy provést. K vytvoření takového agenta tedy nebudeme potřebovat žádný speciální program, můžeme jej vytvořit třeba v aplikaci TextEdit. Agent, se kterým budeme dále pracovat, vypadá následovně:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>cz.mujmac.sampleagent</string> <key>LowPriorityIO</key> <true/> <key>ProgramArguments</key> <array> <string>/Library/Application Support/Play Random Track.app</string> </array> <key>StartInterval</key> <integer>60</integer> </dict> </plist>
Zkopírovat jako archiv (4 KB)
Co jednotlivé klíče znamenají?
Label řetězec – unikátní jméno agenta ve formátu doména.jméno, pod tímto jménem bude náš agent zobrazován v launchd.
LowPriorityIO boolean – oznamuje, že náš agent má nízkou prioritu.
ProgramArguments seznam řetězců – cesta k našemu programu (případně i s parametry), uvádí se až ke spustitelnému souboru. Pokud jsme uložili naše skriptové ukázky jako "Aplikaci" (Application), bude cesta vypadat takto:
/cesta/program.app
Pokud ovšem uložíme skripty jako "Aplikační balík" (Application bundle), bude již cesta vypadat takto:
/cesta/program.app/Contents/MacOS/program
StartInterval číslo – nastavení intervalu spouštění v sekundách (hodnoty volte vyšší než 30 sekund).
Soubor uložte na plochu jako prostý text v kódování Unicode UTF-8, pod jménem cz.mujmac.sampleagent.plist (koncovka .plist je povinná). Před uložením může být zapotřebí převést obsah dokumentu do čistě textové podoby, učiníme tak příkazem Převést na obyčejný text (Make Plain Text) z nabídky Formát (Format).
Nyní vezměte ukázkovou aplikaci "Play Random Track.app" (koncovka .app je v programu Finder skrytá) a tuto přesuňte do složky "Application Support", která se nachází ve složce "Knihovna" (Library) na disku s aktivním systémem. Výsledná cesta ke spustitelnému souboru poté bude "/Library/Application Support/Play Random Track.app" – což odpovídá hodnotě prvního řetězce v klíči ProgramArguments.
V tuto chvíli máme aplikaci, kterou budeme chtít spouštět v časovém intervalu, připravenou ve složce "Application Support", máme též vytvořený konfigurační soubor "cz.mujmac.sampleagent.plist". Zbýt tedy poslední krok – oznámit systému náš záměr a seznámit se s příkazy, kterými můžeme chod agenta ovlivňovat. Aby systém mohl s naším agentem začít pracovat je nutné jej umístit do správné složky. Pro spouštěcí agenty jsou vyhrazeny následující místa:
~/Library/LaunchAgents – sem umístíme agenta, který bude spuštěn pouze v konkrétním uživateli (složku LaunchAgents bude pravděpodobně třeba vytvořit nejprve manuálně).
/Library/LaunchAgents – sem umístíme agenta, který bude spuštěný pod libovolným uživatelem (složka LaunchAgents by již měla být k dispozici).
V našem případě použijeme umístění druhé, společné všem uživatelům. Nejprve spustíme program Terminál (Terminal). V prvním kroku zkopírujeme z plochy soubor "cz.mujmac.sampleagent.plist" do cílové složky: sudo mv ~/Desktop/cz.mujmac.sampleagent.plist /Library/LaunchAgents/cz.mujmac.sampleagent.plist
(bude vyžadováno heslo správce)
Poté si cílovou složku nastavíme jako pracovní: cd /Library/LaunchAgents
Pro kontrolu si zobrazíme její obsah: ls -l
Nastavíme uživatele/skupinu: sudo chown root:admin cz.mujmac.sampleagent.plist
Můžeme ověřit změny: ls -l
Změníme nastavení práv: sudo chmod 664 cz.mujmac.sampleagent.plist
Ověříme provedené změny: ls -l
Výstup v terminálu by měl vypadat nějak takto:
-rw-rw-r-- 1 root admin 443 Apr 27 11:53 cz.mujmac.sampleagent.plist (hodnoty "443 Apr 27 11:53" mohou být odlišné)
Pokud nyní restartujeme počítač, bude po startu počítače náš první spouštěcí agent automaticky registrován (načten) a začne v zadaném intervalu spouštět požadovaný program. Agenta můžeme též spustit manuálně ihned, bez restartu, příkazem: launchctl load /Library/LaunchAgents/cz.mujmac.sampleagent.plist
Zobrazit spuštěné agenty pro stávajícího uživatele můžeme příkazem: launchctl list
Na výstupu by se náš agent měl zobrazit v podobě: cz.mujmac.sampleagent
Je-li náš agent již načtený v rozhraní launchd, můžeme jej manuálně kdykoliv spustit příkazem: launchctl start cz.mujmac.sampleagent
V tomto případě se nevyčká stanoveného intervalu, ale úloha spravovaná agentem se vykoná okamžitě.
Naopak přerušit právě prováděnou úlohu můžeme příkazem: launchctl stop cz.mujmac.sampleagent
Tento příkaz pouze zastaví aktuální úlohu, v následujícím nastaveném intervalu se již opět normálně provede. Manuálně můžeme též našeho agenta z rozhraní launchd odstranit a ukončit tak jeho činnost zcela, příkazem: launchctl unload /Library/LaunchAgents/cz.mujmac.sampleagent.plist
Stejným způsobem si můžete vytvořit samostatné spouštěcí agenty i pro zbylé dva ukázkové programy. Ještě zmíním jednu drobnost, sledujte na displeji v iTunes čas uplynulý od začátku skladby a porovnejte si jej s intervalem spouštění programu (interval se počítá od zahájení spouštění).
Závěrem důležité upozornění, spouštěcí agenti pracují ihned po načtení systému, tedy i pokud ještě není přihlášený uživatel. Stejně tak pokud uživatele odhlásíme, nezrušíme tím činnost agentů. V našem případě, kdy jako ukázky spouštíme běžné programy, nastane ovšem problém, pokud dojde k pokusu o spuštění v okamžiku, kdy není uživatele přihlášený. Proces, který se stará o spouštění a ukončování aplikací, chybně v takovém případě registruje náš program a ten již nepůjde spustit. Obecně platí, že pokud launchd desetkrát po sobě obdrží od agenta v návratu chybový stav, trvale jej odstraní (unload).
Pro naše účely si můžeme pomoci jednoduchým trikem. Nejprve přesměrujeme chybový výstup z agenta do ztracena. Provedeme tak přidáním následujícího klíče do konfiguračního souboru.
<key>StandardErrorPath</key> <string>/dev/null</string>
Nyní si vytvoříme shell skript, který příkazem "open" spustí náš ukázkový program. Skript může vypadat nějak takto:
#!/bin/sh /usr/bin/open '/Library/Application Support/Play Random Track.app'
Skript uložte jako prostý text třeba do složky shodné s ukázkovým programem (/Library/Application Support). Důležité je nastavení shodných práv s naším agentem (viz výše) a zejména nastavení spouštěcího atributu (execute bit), což provedeme příkazem: sudo chmod +x /cesta/program
Poté z našeho spouštěcího agenta nevoláme přímo náš ukázkový program, ale tento skript, který poslouží jako prostředník. Před případnými úpravami agenta jej nejprve odstraňte z launchd (unload).
Čtenáři ovládající AppleScript si teď asi řeknou, proč na to jdu tak složitě, AppleScript přece sám o sobě umí provádět kód v intervalu. Uvedu to hned na pravou míru, v článku popisuji řešení, která se dají uplatnit univerzálně a konkrétní ukázky v jazyce AppleScript jsem volil především pro jejich srozumitelnost. Možnosti launchd jsou výrazně větší, umožňují například "udržovat" nějaký proces/program neustále spuštěný, pracovat pod uživatelem "root" a to i v okamžiku, kdy žádný standardní uživatel není přihlášený, umí spouštět procesy/programy v pevně stanovaný čas/datum. Tady by nám již samotný AppleScript nepomohl. Abych se však ještě vrátil k provádění nějakého programu (respektive části jeho kódu) výlučně v prostředí AppleScript. Prohlédněte si poslední ukázku:
on run tell application "System Events" if (not ((name of every login item) contains "OnIdle")) then make new login item at end ¬ with properties {name:"OnIdle", kind:"APPLICATION", path:(path to me)} end if end tell end run on idle beep 1 return 5 end idle
Zkopírovat jako archiv (4 KB)
Pokud skript uložíte jako stále spuštěnou aplikaci (stay-open), bude při jejím spuštění nejprve provedena událost "on run", ve které program sám sebe přidá k položkám po spuštění (správu těchto položek naleznete v Předvolbách systému (System Preferences) v panelu Účty (Accounts) v oddílu Přihlášení (Login Items). Poté program začne vykonávat událost "on idle", kdy každých pět sekund (return 5) přehraje jednou výchozí systémový výstražný zvuk (beep 1). Zkuste si nyní namísto řádky "beep 1" vložit kód některé z předchozích ukázek a nastavte hodnotu return například na jednu minutu (return 60).
Záměrem tohoto dvojdílného článku bylo ukázat možnosti, kterými systém disponuje, a nastínit i možné příklady praktického využití na srozumitelných ukázkách. Jistě vás napadne celá řada dalšího využití a různých úprav. Napište je prosím do diskuze pod článkem a inspirujte tak další uživatele.
Obsah seriálu (více o seriálu):
Tématické zařazení:
» Rubriky » Tipy a Triky