AmigaDOS VI.Jan Hlavatý
V tomto posledním díle seriálku o AmigaDOSu se konečně podíváme na dávkové
soubory - scripty. Co že je to vlastně script? Pokud jde o formu, je to textový soubor, který
obsahuje příkazy AmigaDOSu - na každém řádku jeden. Tato skupina příkazů tvoří
dohromady jednoduchý program, který plní nějakou funkci. Můžete si je představit
jako makra v textovém editoru místo abyste pokaždé vypisovali sérii příkazů
nutnou pro určitou činnost, zapíšete všechny tyto příkazy do souboru scriptu a
pak už je jen pouštíte. Není to však jen pouhá sekvence příkazů - lze použít i
podmíněné větvení programu a skoky, takže se vlastně jedná o jakýsi jednoduchý
programovací jazyk. Standardní umístění scriptů je v adresáři „S“ (jako
„script“) na systémovém bootovacím disku, kterému je přiřazen assign „S:“.
Podívejme se tedy na originální systémovou disketu Workbenche do adresáře S.
Budu popisovat scripty které jsou součásti systému 3.1. Na 3.0 jsou, pokud vím,
až na malé rozdíly skoro stejné a stejně je sem vypíšu, takže nebude vadit,
jestli je nemáte...
Než ale začneme s vysvětlováním scriptů, musíme probrat ještě jeden příkaz
AmigaDOSu, jehož detailní popis jsem si úmyslně nechal až sem - příkaz EXECUTE.
Ten totiž tvoří úplný základ pro zpracování scriptů. Abych byl přesný, on je
totiž provádí - čte script řádek po řádku a interpretuje příkazy, které tam
najde. Kromě toho umožňuje také používat ve scriptech lokální a globální
proměnné a také je schopen předat scriptu argumenty, jako je třeba jméno
souboru. Tyto operace provádí pomocí nahrazování útvarů jako je označení
proměnné textem (obsahem proměnně) před tím, než je příkaz skutečně vykonán.
EXECUTE rozeznává v scriptovém souboru svoje vlastní příkazy, místa pro
nahrazení textu a komentáře. Speciální příkazy začínají vždy tečkou (nebo jiným
znakem, který je definován místo tečky speciálním příkazem) a nacházejí se vždy
na začátku řádku. Místa pro nahrazení textu se mohou nacházet kdekoli na řádku a
jsou dvojího druhu - jednak místa označující lokální nebo globální proměnné,
jejichž obsah se má vložit na tomto místě textu - ty mají tvar $jméno_proměnné
(tj. znak $ (dolar) za kterým následuje bezprostředně jméno proměnné), a druhak
jsou to místa označující, kam se mají vložit argumenty scriptu. Ta mají tvar
jména argumentu uzavřeného do speciálních závorek. Tyto závorky jsou defaultně
„<“ a „>“, ale protože tyto znaky se hojně používají k přesměrovávání
standardního vstupu a výstupu, bývají záhy předefinovávaný na závorky složené
(„{“ a „}“).
Jak si jistě všímáte, všechny znaky mající speciální význam lze předefinovat na
znak jiný, aby se předešlo případným konfliktům, pokud by se daný znak měl
použít jinak v některém příkazu scriptu. Argumenty scriptu se zadávají jako
standardní template pomocí příkazu „.KEY“ (zkráceně „.K“). Tento příkaz lze
použít ve scriptu jen jednou a musí to být hned na prvním řádku scriptu. Jedinou
výjimkou oproti normálním template je nemožnost použít Typy argumentů /N a /M,
protože EXECUTE předpokládá, že výsledkem zpracování template funkcí dos.library
ReadArgs() bude pointer na řetězec, ale u /N je výsledkem integer hodnota (tj.
nesmyslný pointer) a u /M pointer na pole pointerů na řetězce (nesmyslná data).
/N se prostě nepoužije, /M lze do určité míry nahradit pomocí /F.
Klíčová slova uvedená v template pro každý argument pak, uzavřena do speciálních
závorek,znamenají, že na toto místo se má vložit text, který byl zadán jako
odpovídající argument. Kromě toho může v těchto speciálních závorkách být ještě
kombinace dvou znaků dolaru, „$$“. Ta bude nahrazena číslem procesu, na kterém
se script provádí. K čemu je to dobré? Kvůli multitaskingu. Představte si že
máte script, který si během své práce vytváří pomocný soubor v T: a tento
pomocný soubor má určité jméno. Problém nastává, když tento script spustíte
současně ve dvou procesech shellu - oba dva spuštěné scripty se budou současně
snažit pracovat se stejným souborem a dojde ke konfliktu. No, a tady se nám
pěkně hodí číslo procesu, které je pro každý proces unikátní - my z něj totiž
uděláme součást jména onoho pomocného souboru. A je vymalováno...
Pokud jde o argumenty, v template je možné definovat nepovinný argument, který
je možno vynechat. EXECUTE poskytuje dvě možnosti, jak takovému nepovinnému
argumentu přiřadit implicitní hodnotu. Mezi těmito dvěma způsoby je malý rozdíl.
První způsob je příkaz „.DEF“.
Tento příkaz má dva argumenty jméno argumentu shellu, jehož implicitní hodnotu
má nastavit, a textový řetězec, který se použije jako tato implicitní hodnota.
Výsledek má pak takový efekt, že když neuvedete daný argument, je to jako byste
tento argument uvedli jako text definovaný pomocí .DEF. Druhý způsob je trochu
odlišný. Na každém místě, kde pomocí speciálních závorek vkládáte hodnotu
argumentu do textu, napíšete dovnitř speciálních závorek hned za jméno argumentu
znak „$“ (dolar), a pak požadovanou implicitní hodnotu. Rozdíl oproti první
metodě je v tom, že tato implicitní hodnota může být u každého místa vkládání
hodnoty argumentu jiná.
Pokud jde o komentáře, jako komentář se bere vše počínaje znakem „;“ (středník)
až do konce řádku, nebo každý řádek začínající tečkou, za kterou následuje
mezera. Prázdný řádek komentáře by měla být kombinace „.“.
Pro předefinovávaní speciálních znaků v případě konfliktu slouží tyto příkazy:
.BRA <znak> pro předefinování levé speciální závorky, původně „<“
.KET <znak> pro předefinování pravé speciální závorky, původně „>“
.DOT <znak> pro předefinování tečky na začátku příkazů, původně „.“
.DOL <znak> pro předefinování znaku dolar, původně „$“.
Tolik k příkazu EXECUTE.
Ted se podíváme na nějaké scripty. Script který nás bude zajímat nejdřív je
„startup-sequence“. Už jste o ní asi slyšeli - je to dávkový soubor, který se
spustí automaticky při startu systému z bootovacího disku a je zodpovědný za
nabootování systému. Tento skript je otištěn na protější straně, ale raději se
podívejte na originální soubor z vaší Workbenchové diskety. Teď se podíváme co
to vlastně dělá.
Na prvních dvou řádcích vidíme komentáře. Všimněte si konstrukce $VER:. Ta
umožňuje vyhledávat automaticky číslo verze souboru pomocí příkazu VERSION, a
jak vidíte, nejen v executable souborech, ale i v textu.
SETPATCH opraví případné chyby v ROM, je tedy logicky na prvním místě.
VERSION zjistí verze Kickstartu a Workbenche a vytvoří dvě lokální (!) proměnné,
„Kickstart“ a „Workbench“, do nichž zapíše jejich verze.
ADDBUFFERS přidá 15 bloků vyrovnávací paměti (bufferů) disketové jednotce.
FAILAT 21 zajistí pokračování provádění startup-sequence i v případě nějaké
chyby, aby ubohý věci neznalý user nepřišel o svůj Workbench navždy...
MAKEDIR vytvoří potřebné adresáře v RAM: pro clipboard a systémová nastavení.
COPY pak zkopíruje systémová nastavení z archivu na disku (ENVARC:) do paměti
(ENV:). Tímto způsobem je realizována dočasná změna systémových nastavení pomocí
„USE“ (použít) - když dáte Use, systémové nastavení sc uloží jenom do ENV:, a
při případném restartu počítače bude obnoveno původní nastavení z ENVARC:. Pokud
však dáte SAVE (uložit), zapíše se nové nastavení jak do ENV:, tak i do ENVARC:,
takže tam zůstane natrvalo. Jak jste jistě uhodli, jedná se tu o nastavení
preferencí.
Dále si script pomocí RESIDENT nahraje dva dále hojně používané příkazy ASSIGN a
EXECUTE rezidentně do paměti, čímž odpadne nutnost tyto příkazy při jejich
použití pokaždé nahrávat z disku - což zvláště oceníte v případě bootování z
diskety.
Následuje hrstka ASSIGNů, kterážto našteluje veškeré standardní systémové
assigny. Všimněte si připojení SYS:Classes k LIBS:, což je důvod, proč vám
nechodí datatypy, pokud nabootujete bez startup-sequence.
Následuje část, která je tu nově v 3.1. Vzhledem ke stále se zmenšujícímu
volnému místu na systémových disketách jsou výrobci nuceni přesouvat stále více
obsahu Workbench diskety na ostatní diskety. Tato skupina příkazů otestuje,
zdaje na bootovací disketě adresář L: a pokud ne, vytvoří zpožděný odkaz na
tento adresář na disketě Extras3.1.
Další část způsobí zrušení automaticky vygenerovaného odkazu FONTS: na
SYS:fonts, tudíž způsobí, že si systém řekne o disketu FONTS:. To vše pouze v
případě, že na bootovací disketě adresář fonts není.
BINDDRIVERS provede nahrání ovladačů pro rozšiřující karty umístěných v
SYS:Expansion a jejich připojení k hardwaru karet. Majitele A1200 toto asi
nemusí zajímat.
MOUNT na následujícím řádku zamontuje všechna dosová zařízení, která najde v
adresáři DEVS:DosDrivers. To způsobí, že pouhým přetažením ikony zařízení do
DEVS:DosDrivers bude toto zařízení automaticky aktivováno při každém rebootu.
Povšimněte si patternu, který říká „Vše v devs:dosdrivers, co nejsou ikony“
Následující blok provede inicializaci ovladačů monitorů v DEVS:Monitors. Všechny
tyto ovladače jsou executable soubory a je třeba je spustit. Pokud existuje
ovladač „VGAOnly“, je třeba ho spustit jako první - což je zajištěno. Následuje
trik, který stojí za povšimnutí. Jde o to, jak spustit skupinu programů zadanou
pomocí patternu. Finta spočívá ve využití příkazu LIST (viz náš seznam příkazů),
kterým se vypíší všechny soubory odpovídající patternu takovým způsobem, že
vznikne pomocný soubor, který obsahuje na každém řádku jméno souboru. Když se
pak tento pomocný soubor spustí jako script příkazem EXECUTE, každé jméno
souboru se interpretuje jako příkaz ke spuštění tohoto souboru... a je to.
Následně je pomocný soubor vymazán.
Následuje nastavení globálních proměnných příkazem SETENV Vytvořeny jsou tří
proměnné - Language, Workbench a Kickstart. Všimněte si, že už máme lokální
proměnné Workbench a Kickstart od příkazu VERSION. Tady se z nich zkopírováním
vytvoří proměnné globální, a původní lokální proměnné se zruší.
ADDDATATYPES inicializuje systém datatypů ze souborů v DEVS:Datatypes a vytvoří
jejich databázi pro datatypes.library.
Následující blok příkazů je opět novinka v 3.1 - pokud je k dispozici dostatek
paměti, jsou do paměti nahrány některé knihovny a katalogy uložené na disku, aby
uživatel nemusel znova vkládat Workbenchovou disketu. Všimněte si vnořeného
spuštění programu IPrefs, který má na starosti preference systému - načte
všechny systémové konfigurace z ENV: a aktualizuje hodnoty nastavení systému
podle nich.
Nahrávání katalogů pro jiné jazyky než angličtinu probíhá až poté, co je
nastavený jazyk znám od IPrefs. Povšimněte si také zjišťování volné paměti
pomocí příkazu AVAIL v obrácených apostrofech - text který program v obrácených
apostrofech po svém spuštění vypíše, je vložen na místo této konstrukce a tato
číselná hodnota je následně porovnávána s konstantou pomocí příkazu IF.
CONCLIP je utilitka, která umožňuje používat clipboard v oknech zařízení CON:.
Pomocí PATH je nastavena cesta pro vyhledávání příkazů. Ta se pak bude dědit do
všech dceřinných procesů shellu.
Následuje důležitá část - spuštění dávkového souboru user-startup. Jak název
napovídá, je určen pro uživatele, aby mohl přidávat příkazy, které se mají
provést při bootování a přitom nemusel měnit startup-sequenci. User-startup
funguje jako jakýsi podprogram startup-sequence. Příkazy v něm uložené se
automaticky provedou na správném místě startup-sequence a nehrozí její
poškození. Navíc lze příkazy do user-startup snadno přidávat pouhým připojením
na konec souboru, narozdíl od startup-sequence, kde by bylo nutno se nějak
trefit ještě před LoadWB a EndCli, což by byl nemalý problém. Všechny programy
používající standardní Installer automaticky přidávají do user-startupu, pokud
už musí něco cpát do bootovací sekvence. Do user-startup se v naprosté většině
případů přidávají příkazy ASSIGN, případně i PATH.
Následuje odstranění rezidentně uložených příkazů ASSIGN a EXECUTE z paměti a
spuštění Workbenche. Proces bootovacího shellu pak končí příkazem ENDCLI a
jediným uživatelským procesem zůstává Workbench.
Jak vidíte, startup-sequence nemá žádné argumenty. Podíváme se tedy na nějaký
script s argumenty.
Ve stejném adresáři jako startup-sequence se nachází jiný script, který je
součástí systému - „SPat“. Jeho účelem je umožnit použití patternu u příkazu,
který patterny neumí. Tady je: .key COM/A,PAT/A,OPT1, OPT2, OPT3, OPT4
.bra {
.ket }
; $VER: Spat 40.1 (9.2.93)
; Do wildcards for single argument commands
FailAt 21
List >T:q{$$} (PAT} LFORMAT „{COM} *“%s%s*“ {OPT1} {OPT2} {OPT3} {OPT4}“
IF NOT FAIL
Execute T:q{$$}
Else
Echo „{PAT} not found“
EndIF
Delete >NIL: T:q{$$} QUIET
FailAt 10 Jak vidíte, na prvním řádku scriptu je definice template pro argumenty tohoto
scriptu. Jsou zde dva povinné argumenty - COM (příkaz který se má provádět) a
PAT (pattern, udávající soubory na které má být COM spuštěn). Dále jsou tu čtyři
nepovinné argumenty OPT1, OPT2, OPT3, OPT4, které budou vždy předány příkazu za
jménem souboru.
Technologie dosažení cíle je zde podobná jako u inicializace monitorů ve
startup-sequenci výše. Je vytvořen pomocný dávkový soubor pomocí příkazu LIST,
který je posléze spuštěn. Všimněte si správného vygenerování jména pracovního
souboru na základě čísla procesu. Tady vidíte, že příkaz LIST je se svým
variabilním výstupním formátem velice užitečný.
Nakonec ještě jednu maličkost z mého počítače. Jsem spokojeným majitelem
turbokarty Blizzard 1230IV a 8MB paměti. Moje startup-sequence je tedy vzhledem
k dostatku paměti nacpaná spoustou hovadinek. Blizzard je však vypínatelný,
potřebuji tedy občas nabootovat bez 8MB fastram. A ejhle - s původní
startup-sequencí mi bez fastram zbude volných bratru nějakých 700kB. Hrůza!
Udělal jsem si tedy startup-sequence dvě - jednu tučnou pro dostatek paměti a
jednu ořezanou pro bootování s vypnutým Blizzardem. Původní startup-sequenci
jsem uložil pod jménem Startup-sequence.Fast, Ořezanou pod jménem
startup-sequence.NoFast a startup-sequenci jsem přepsal na: assign T: RAM:
IF VAL AVAIL FAST GT 0
execute s:startup-sequence.Fast
quit
ELSE
execute s:startup-sequence.NoFast
quit
ENDIF
;-- fake: kouli installeru...
IF EXISTS s:user-startup
Execute s:user-startup
EndIF Assign T: do RAM: je tam jen kvůli execute. Příkazem AVAIL si zjistím,
podobně jako výše ve startup-sequenci 40.3, velikost volné FAST RAM, a je-li
nějaká, volám startup-sequence.Fast. Pokud fastram není, volám
startup-sequence.NoFast. Volání user-startup je tady pouze kvůli Installeru,
který si to kontroluje - ve skutečnosti se sem program nikdy nedostane. V
startup-sequence.NoFast také volám user-startup.NoFast místo user-startup a mám
jiný adresář ENVARC: pro bootování bez fastram - tj. je třeba trochu pozměnit
startup-sequenci v rámci ořezávání.
To by bylo asi tak všechno, co bych vám chtěl sdělit... hurá na experimenty! Asi
už vám došlo, že scripty se nehodí na nějaké superinteligentní programování -
spíš vám ušetří práci.
Pokud chcete dělat něco inteligentnějšího (například automatickou kompilaci
zdrojového textu přímo z textového editoru tak, že potřebný kompilátor se zjistí
podle koncovky jména zdrojového textu), budete muset použít ARexx - ten je na to
dělaný...
Doufám, že vám to k něčemu bylo a že vás už nemusí tolik mrzet, že jste k
počítači nedostali manuál k AmigaDOSu... ; $VER: Startup-Sequence_LD 40.3 (31.8.93)
; Startup-Sequence for low-density floppies
C:SetPatch QUIET
C:Version >NIL:
C:AddBuffers >NIL: DF0: 15
FailAt 21
C:MakeDir RAM:T RAM:Clipboards RAM:ENV RAM:ENV/Sys
C:Copy >NIL: ENVARC: RAM:ENV ALL NOREQ
Resident >NIL: C:Assign PURE
Resident >NIL: C:Execute PURE
Assign >NIL: ENV: RAM:ENV
Assign >NIL: T: RAM:T
Assign >NIL: CLIPS: RAM:Clipboards
Assign >NIL: REXX: S:
Assign >NIL: PRINTERS: DEVS:Printers
Assign >NIL: KEYMAPS: DEVS:Keymaps
Assign >NIL: LOCALE: SYS:Locale
Assign >NIL: LIBS: SYS:Classes ADD
Assign >NIL: HELP: LOCALE:Help DEFER
IF NOT EXISTS SYS:L
Assign >NIL: L: Extras3.1:L DEFER
EndIF
IF NOT EXISTS SYS:Fonts
Assign FONTS:
EndIF
BindDrivers
C:Mount >NIL: DEVS:DOSDrivers/~(#?.info)
IF EXISTS DEVS:Monitors
IF EXISTS DEVS:Monitors/VGAOnly
DEVS:Monitors/VGAOnly
EndIF
C:List >NIL: DEVS:Monitors/~(#?.info|VGAOnly) TO T:M LFORMAT „DEVS:Monitors/%s“
Execute T:M
C:Delete >NIL: T:M
EndIF
SetEnv Language „english“
SetEnv Workbench $Workbench
SetEnv Kickstart $Kickstart
UnSet Workbench
UnSet Kickstart
C:AddDataTypes REFRESH QUIET
IF „C:Avail TOTAL“ GE „1250000“ VAL
C:LoadResource LIBS:diskfont.library LIBS:iffparse.library LIBS:asl.library
LIBS:commodities.library
C:IPrefs
IF NOT $Language EQ „english“
CD LOCALE:Catalogs/$Language
C:LOadResource Sys/workbench.catalog Sys/libs.catalog Sys/prefs.catalog
Sys/commodities.catalog Sys/utilities.catalog
CD SYS:
EndIF
Else
C:IPref
EndIF
C:ConClip
Path >NIL: RAM: C: SYS:Utilities SYS:Rexxc SYS:System S: SYS:Prefs SYS:WBStartup
SYS:Tools
IF EXISTS S:User-Startup
Execute S:User-Startup
EndIF
Resident Execute REMOVE
Resident Assign REMOVE
C:LoadWB
EndCLI >NIL: Vytlačiť článok
Pozn.: články boli naskenované ako text a preto obsahujú aj zopár chýb. Taktiež neručíme za zdrojové kódy (Asm, C, Arexx, AmigaGuide, Html) a odkazy na web. Dúfame, že napriek tomu vám táto databáza dobre poslúži.
Žiadna časť nesmie byť reprodukovaná alebo inak šírená bez písomného povolenia vydavatela © ATLANTIDA Publishing
none
|