Pakkfailide feilimisest
Eestikeelses
arvutiteaduses on pätukate, bät- (.bat / .cmd ) failide
kohta lõpuks juurdunud omakeelne sõna pakkfail.
Las tal siis edasi
tähistada neid veidraid natukene nagu programmeerimiskeelt
meenutavaid .bat või .cmd laiendiga faile.
Märkus:
Kuigi ma kasutan siin enamasti mõisteid .bat keel / .bat failid, tuleks praegu kasutada pakkfailide tegemisel eranditult .cmd laiendit. BAT tuleneb sõnast batch - pakk, ports, ahjutäis...ja sellest siis selline tõlketermin - pakkfail.
Tõsi, .bat laiendiga failid käivituvad sama edukalt, kui .cmd laiendiga, nii et ikkagi maitse asi.
Märkus:
Kuigi ma kasutan siin enamasti mõisteid .bat keel / .bat failid, tuleks praegu kasutada pakkfailide tegemisel eranditult .cmd laiendit. BAT tuleneb sõnast batch - pakk, ports, ahjutäis...ja sellest siis selline tõlketermin - pakkfail.
Tõsi, .bat laiendiga failid käivituvad sama edukalt, kui .cmd laiendiga, nii et ikkagi maitse asi.
Päris mööda pakkfailidest ei
pääse, kui on vaja tegelda W administreerimisega. Tänapäeval ei
jõua W administraator igale poole ja hoolimata ühe või teise
vahendi headustest või halbustest on vajalik kasutusele võtta iga
asi, mis tööd hõlbustaks.
Pakkfailide ainuke hea
omadus on see, et need jooksevad enam-vähem kõikides windowsi
perekonna masinates ja vahel on see administraatori jaoks põhiline
kriteerium. Ülejäänud vahendite kohta seda alati öelda ei saa.
Seetõttu ei pruugi muud üle jääda, kui veidrused .bat keeles välja kannatada ja ära õppida.
Seetõttu ei pruugi muud üle jääda, kui veidrused .bat keeles välja kannatada ja ära õppida.
Programmeerimist alles
õppijate jaoks aga on pakkfailide "võlu" pigem selles, et
see “keel” või skriptimisvahend on skandaalselt põrunud,
kohati lausa jabur ja selles mõttes õppuritele erakordselt sobiv
õppematerjal, et näidata, kuidas ehk ei tohiks mõnda
programmeerimiskeelt üles ehitada.
Üldiselt bash
programmerimise studeerimise järel võib öelda ka Bourne
again kesta kohta just mitte kõige paremaid sõnu, aga piisab
vaid, kui tulla ja hakata nikerdama skripte pisipehmete akende jaoks
- kohe hakkad taga igatsema vana head Unix-it.
Windows-i arendajatele
on olnud ka paremaid aegu. Ühel ilusal ajal mõeldi, et Windowsi
kesta programeerimiskeeleks võiks olla VBS ja see hakkas levima ja
ongi veel õnneks üsna levinud siin ja seal. Või siis JavaScripti
MS versioon JScript.
Ja siis tuli vist
Balmeril pähe mõtte aretada välja täiesti oma eriline keel nimega
Power Shell ja täpselt sama ämber algas otsast peale ja sellele ei
paistagi MS maailmas lõppu tulevat...
Edsger Dijkstra on Coboli kohta öelnud et selle kasutamine invaliidistab mõistuse ja seetõttu tuleks selle õpetamist käsitleda kriminaalkuritööna. <16>
Mina päris nii ei julgeks väita. Mina peaksin siis ka ju olema vaimuinvaliid, pomisen omaette ...
...andmebaaside
nikerdamine peaks olema vastav tunnistuse saamisel täiesti piisav
kriteerium.
Endasuguste kaitseks
julgen laliseda, et tänapäeva koodinikerdaja peab olema tuttav
mitmesugust laadi asjandustega ja kasutajad ei küsi, kas ja
missugune töövahend parajasti kasutusel on, tema tahab näha
töötavat arvutit, millega teha tööd.
Kui Dijkstra loogika
kehtiks, tuleks kõik IT-d õpetavad õppejõud viivitamatult
vanglasse toppida, nii 12. aastaks ja nende aretatud vaimuinvaliide
kibekiiresti ravima hakata. Ja kuna neid progejate kambas on enamik,
siis mõneks ajaks peatada tsivilisatsiooni toimimine, seniks, kuni
psühhiaatrid oma tööga maha saavad, kui üldse saavad.
Ei ole lihtsalt
võimalik, et oma elutegevuse keskel programmeerijal ei tuleks
tegemist teha eriliselt jaburate programmeerimiskeelte veel
jaburamate konstruktsioonidega...
Aga tuleme nüüd siis tagasi vaimuinvaliidide erilise koondumiskoha - MS .bat failide programmeerimise juurde.
Aga tuleme nüüd siis tagasi vaimuinvaliidide erilise koondumiskoha - MS .bat failide programmeerimise juurde.
I Hallo, Maailm -
kahjuks koos lisanditega ...
Otsige üles oma op.
süsteemi versioonile vastavalt run rida ja kirjutage sinna cmd.
Kui midagi ära ka tahate teha arvuti juures, käivitage cmd aken
administraatori rezhiimis. Kirjutage sinna laiust juurde, mode
100,100 avab võimaluse 100 sümbolit ritta panna (niinimetatud
prompt võtab sellestki palju ära, aga tühja sellest).
Esimene asi, mida
vaimuinvaliidiks saamiseks on vaja õpetada, on programm nimega
Hallo
maailm.
See tüütus sai alguse
muidugi Kerninghami ja Ritchie C vanast testamendist <15>
ja kestab tänase päevani. Umbes nagu Piibli esimene rida
kristlastele:
Alguses
lõi Jumal taeva ja maa
Programmeerimise
ülekaalukalt popima lause “Hallo maailm” väljastamiseks
on igal pool oma võlusõna. W käsuaknas on selleks sama sõna, mis
Unix-is: echo.
> echo “Hallo
maailm!”
Ja saate .... saate
mille
Saate
“Hallo maailm!”
Oot, oot... aga miks
jutumärgid kaasa tulid?
Igal pool mujal
jutumärke ei panda kaasa, see on pakend, see eraldab echo
järel tuleva käsurea argumendi alguse ja lõpu ülejäänud reast
ja sageli on see hädavajalik, sest mingile programmile on vaja ühes
tükis, ühe argumendina mingid andmed ette sööta, ja selle järel
tuleb järgmine argument, või andmejupp, mis peab olema eraldatud
eelmisest üheselt. Lisatud jutumärgid küll päästavad nende sisu
mõningate erisümbolite erikohtlemise eest, aga mitte kõigi.
Ühekordsed jutumärgid on
.bat-s täiesti kasutud isegi selles mõttes.
Siit algab suur jama, sest .bat programmide argumendid on vaja igaks juhuks jutumärkidest vabastada, mõnikord peavad need jälle sõnel - stringil ümber olema ja kui neid ülearu saab, siis ei saa programm mitte millestki aru.
.bat-s täiesti kasutud isegi selles mõttes.
Siit algab suur jama, sest .bat programmide argumendid on vaja igaks juhuks jutumärkidest vabastada, mõnikord peavad need jälle sõnel - stringil ümber olema ja kui neid ülearu saab, siis ei saa programm mitte millestki aru.
II Muutujatest, mis
ei taha muutuda
Igas normaalsusele
pürgivas programmeerimise keeles on olemas muutujad. Isegi pisipehme
bat keeles.
Lisaks kõigele on igas operatsioonisüsteemis olemas keskkonnamuutujad, mis ütlevad käivituse järgselt ja logimise järgselt süsteemile olulisi asju, näiteks ka selle, kes on sisse loginud ja millised on tema eelistused (kasutaja keskkonnamuutujad), ning süsteemimuutujad, mis kehtivad kõigile.
Lisaks kõigele on igas operatsioonisüsteemis olemas keskkonnamuutujad, mis ütlevad käivituse järgselt ja logimise järgselt süsteemile olulisi asju, näiteks ka selle, kes on sisse loginud ja millised on tema eelistused (kasutaja keskkonnamuutujad), ning süsteemimuutujad, mis kehtivad kõigile.
Nende kõigi (keskkonna)muutujate vaatamiseks, aga muutmiseks ainult
(rõhutatult) selles aknas, kus olete käivitanud W cmd.exe, kas
tavakasutajana, või administraatorina, on olemas käsk SET.
Väikene lisamure: (
ärge muretsege, see ongi nii W keskkondades - väikestest
probleemidest saavad kiiresti suured !)
Kui te tahate,
et nende muutujate väärtused jõuaksid ka järgmistesse cmd
akendesse või saavad teie töötavate programmide sisemiseks
teadmiseks, kasutage (täpsemalt, ärge veel kasutage) käsku SETX.
Seda ei ole muuseas kõikides windowsi versioonides ...
SETX kahjuks nõuab
oma muudatuste elluviimiseks rebooti.
GUI-d kasutades
(täpsemad juhendid vt. google, see ei mahu selle kirjutise
raamidesse) saate palju parema tulemuse, muutuja uus väärtus jõuab
kohe vajaminevate programmide teadvusse.
Õnneks enamik
arendajaid ei kasuta programmide töökeskkonna sättimiseks keskkonnamuutujaid, vaid programmid loevad omale
vajaliku info otse registrist. Õnneks on registrisse kirjutamise ja
sealt lugemise vahendid .bat keeles olemas.
Kõikide käibivate
muutujate vaatamiseks tuleb tippida SET ilma lisadeta.
Nende muutujate
vaatlemiseks, mis algavad P tähega, tippige
SET P
(näiteks PATH, mis
alati peab olemas olema).
Muutuja hei
sättimiseks kirjutage SET hei=hai
Täpsemalt siiski, ärge
nii kirjutage.
kirjutage SET
"hei=hai" et täpselt ja konkreetselt ära ütelda,
mida te muutuja hei sisse tahate panna. Varsti näete kohe ühe näite
varal, miks selline kindlustus alati hea on.
Ja siin lõpujutumärk
õnneks ei lähe tõesti hei väärtuse sisusse, nagu võiks
karta W bat-i kombeid juba natuke teades!
Ja ühe muutuja
väärtuse väljastamiseks (vaatamine käibib rohkem programmi
silumisel) kasutage
(või täpsemini,
sellest hiljem, praegu kasutage, hiljem ärge kasutage selles
vormis)
käsku
> echo %hei%
Muutuja nimi tuleb
panna protsendimärkide vahele.
Muutujate
interpreteerimisest ei päästa mitte mingisugused jutumärgid ...
perlis bashis on need võimalused olemas.
Muutuja hei
olemasolu tühistamiseks kirjutage
set "hei="
> set hei
ütleb nüüd, et
Environment
variable hei not defined
Kuidas mitut
käsku ritta panna
Et kannatamatut lugejat
viia kohe II põhiteema juurde - näha oma silmaga ära, kuidas on
võimalik, et muutuja ei muutu - võimalik ainult MS-s(!) - , õpime
mitut käsku paigutama ühte ritta.
Selleks on ampersand,
& .
Normaalsetes, mitte
ajuinvaliididele määratud keeltes on selleks mõni
üldkasutatavatest kirjavahemärkidest - enamasti semikoolon ;
Windows-is on selleks
ampersand ja me näeme kohe, milleks see "hea" on.
Võib-olla tekib teil
soov (enne seda, kui olete ampersandi eriomadustest teadlikuks
saanud)
tavalise Hallo
maailm väljastada Hallo & Hello, maailm!
Saate kurva feili:
Programm teatab teile,
et ...
Hallo
'Hello' is not
recognized as an internal or external command,
operable program or
batch file.
Põhjuseks muidugi see
ampersand - cmd tahab nüüd pärast echo Hallo täitmist
täita asuda järgmise "käsu", Hello täitmise
juurde (märgime, et "," ning "maailm!"
lähevad selle käsu parameetriteks).
Kui aga panete "Hallo
& Hello, maailm!" jutumärkidesse, saate tasuta
kaasväljaandena kaasa jutumärgid ...
ERIMÄRKIDEST
pääsemiseks tavaliselt piisab paosümboli teadmisest, kuigi ka
mujal (bash) on nendega tegemist.
Aga WINDOWS-s on siin asi täiesti E r i l i n e
Aga WINDOWS-s on siin asi täiesti E r i l i n e
Erimärkidest lähemalt
III teema all, kus harjutame alguses tühisena näiva probleemi,
TÜHJA rea tekitamise lahendamist...
Kuidas muutuja
ei muutu
Ok, paneme 2 käsku
ühte ritta. Igaks juhuks tehke enne Set "hei=", et
saada ühesugused tulemid, mine tea, mis väärtusi te hei-le
olete harjutamise käigus vahepeal tekitanud.
Siis tippige
set hei=hai &
echo %hei%
mis bat keeles ütleb,
et paneme muutuja hei väärtuse väärtuseks hai ja
seejärel väljastame ekraanile selle muutuja väärtuse.
Mitte just eriti
intelligentne jupp koodi, aga midagi sarnast võib ju pähe tulla,
panna ühele reale muutuja muutmise käsk ja tulemi(te) väljastamine.
Saate
%hei%
- DOS-i omapäraselt
humoorikas viis ütelda echo peale, et muutujat hei ei
ole olemas.
Tehke sama asja teist
korda - muutuja hei on nüüd tõesti olemas - ja saate
hai
nagu tahtsitegi.
See ei ole uni ja
see ei ole viga, see ongi bat keel, batman...!
See on ka see põhjus,
miks peaks iga õppur, kes kunagi tahab välja mõelda päris oma
programeerimiskeelt (aga kes ei tahaks, iseasi, kas õnnestub!) peaks
teadma bat keelt!
Batmannide keele
väljamõtlejad arvasid algul õigusega, et enne käsu täitmist
tuleks üle vaadata, mis parameetreid käsk sisaldab. Seetõttu käib
bat interpretaator enne käsu täitmist käsu üle, asendades
muuhulgas %xxx% muutuja xxx väärtusega.
Näiteks kirjutatakse
%hei% asemele selle muutuja väärtus enne %hei% -d sisaldava
käsu täitmist.
Sellist asja
nimetatakse muutujalaienduseks (variable expansion). Seda
tehakse kohe enne käsku, sellest termin immediate variable
expansion.
Siis tuli arendajatele
külla Balmer ja ütles: hei, poisid, täna teeme nii, et mitu käsku
saab panna ühele reale või käsud võib panna kokku ühte plokki.
Et bashis on ka midagi sellist ja meie peame ka nii tegema...
See vend aga, kes
immediate variable expansioniga tegeles, arvas, et tema ei
viitsi küll hakata oma programmijuppi täiendama - lihtsalt teeme
nüüd selle variable expansioni enne käsuplokki ära.
Ja edasine, mis selles
käsuplokis juhtub, ei ole minu asi.
Käsuplokkide sekka sattusid ka kõik käsud, mis olid ühele reale aetud & -ga ühendatult. Hiljem näeme, et neid saab ühendada veel && -ga ja koguni || -ga, igal pool sees sama jama - muutuja käsuploki sees ei muutu mitte!
Nii et te võite käsuplokis muuta muutujat palju tahate, ta ei muutu mitte enne, kui see käsuplokk läbi saab ja jõussegi jääb vaid viimane nendest muutustest - viimane omistus hei=%xxxx% ja ülejäänud muudatused lendavad looja karja ...
Käsuplokkide sekka sattusid ka kõik käsud, mis olid ühele reale aetud & -ga ühendatult. Hiljem näeme, et neid saab ühendada veel && -ga ja koguni || -ga, igal pool sees sama jama - muutuja käsuploki sees ei muutu mitte!
Nii et te võite käsuplokis muuta muutujat palju tahate, ta ei muutu mitte enne, kui see käsuplokk läbi saab ja jõussegi jääb vaid viimane nendest muutustest - viimane omistus hei=%xxxx% ja ülejäänud muudatused lendavad looja karja ...
Käsuplokke saate teha
ka ( ) -ga.
sama asi, mis sai
tehtud & -ga, on ( ) -ga eraldatud käsuplokis selline, tehtud
cmd käsureal (enne set "hei=" jälle).
C:\bat>( set
hei=hai
More? echo %hei%
More? )
%hei%
Siin on asi pisut
selgem - bat interpreet ei varja, et ta ootab veel sisendit,
ja käsuploki lõpetamise sulgu ja siis täidab selle, enne muidugi
asendades %hei% tema mitteolemasoleva väärtusega....
.bat
faili enda sees selliseid hoiatavaid More? –sid ei tule.
Sama nali juhtub ka nn.
for tsüklis, millest lähemalt hiljem:
Aga toome ära selle
programmeerimisalase humoreski ja saadava vastuse:
@echo off
set COUNT=0
for %%v in (1 2 3 4)
do (
set /A
COUNT=%COUNT%+ 1
echo %COUNT%
)
echo Ja count on
nüüd: %count%
Saate ekraanile sellise
tulemuse:
0 0 0 0 Ja count on nüüd: 1
Count väärtuseks -
neli korda on teda suurendatud, alati 0-st 1-ni, tuleb ikka
1
Võti selle jama
mõistmiseks: for tsüklis do märgi järel tulevat käsitletakse
ÜHE käsuna...koos FOR-ga.
Kahjuks kuulub for
tsükkel asjade hulka, mida batman peab oskama, teisi
tsüklikonstruktsioone bat keeles lihtsalt ei ole, tõsi,
on veel goto :label
-i abiga tehtav tsükkel - tegelikult kõige kindlam ja parem
tsüklikonstruktsioon bat keeles, sest ei toimi ootamatult.
Mittepühendatutele
selgituseks - set /A tähendab, et nüüd tehakse
aritmeetikat, muidu set sellist asja lihtsalt ei oska.
%%v on for-i
tsüklimuutuja, mis käib läbi väärtused 1,2,3,4 ja praegu mujal
tsüklis ei kajastugi. Millepärast tsüklimuutujad, täiesti
erilised objektid BAT-s, on kahe %% märgiga ja miks nad näiteks
cmd.exe käsuakna realt etteantuna peavad olema ühe % märgiga ja
miks neid mujal kasutada ei saa - seda kõike küsige Balmerilt. Tema
teab, miks sellised imelikud otsused vastu on võetud for tsükli
kavandamisel. Aga selleni veel jõuame...
@echo off lülitab
välja tüütu kaja ja @ märk ütleb echole ise, et ära iseennast
ka kajasta ...
(proovige ilma ka, siis
näete vahet).
Näide, kuidas
mitte
parandada programmeerimiskeele vigu: SETLOCAL
Isegi MS iselaadse
huumorimeelega juba harjunud inimeste seas tekitas selline
"muutujate" käitumine muidugi palju nurinat. Oli veel
nurinat sellegi üle, et kõik muutujad olid globaalsed
- nähtavad tervele programmile või programmide grupile ja iga
programmijupp pääses teise programmijupi muutujatele vabalt ligi.
Ja lõpuks ei olnud .bat keeles algul peaaegu üldse mitte tsükleid, v.a. :label ja goto :label abiga tehtavad tsüklid ja FOR väga nuditud variant.
Ja lõpuks ei olnud .bat keeles algul peaaegu üldse mitte tsükleid, v.a. :label ja goto :label abiga tehtavad tsüklid ja FOR väga nuditud variant.
Seda ajastul, kui iga
programmeerimist õppinu teab Dijkstra kuulsat artiklit
"Goto
considered harmful".<17>
Arendajad lahendasid
need mured ära - uued programmijupid koos moodsama for tsükliga
pandi nn. Extension-ite alla, aga igaks juhuks otsustati, et võiks
teha võimalikuks ka neid mitte kasutada.
Globaalsete muutujatele
lisaks mõeldi välja võimalus tekitada lokaalseid muutujaid
SETLOCAL ja ENDLOCAL vahel.
Ja kõige lõpuks
otsustati spetsiaalse võtme abiga - enableDelayed Expansion panna
muutujad muutma oma väärtusi ka käsuplokkide sees. Aga seda kõike
ikka ka nii, et vanaviisi, kus muutujad ei muutu mitte, saaks ka
edasi jätkata. Kellele sellise jama jätkumist vaja oli, jääb
saladuseks.
Ja kõige tipuks pandi
need 3 täiesti üksteisega mitte seotud asja ÜHE käsu
alla!
Alustame tõeliselt
heast uudisest.
.bat failides,
kui alustada tööd peale @echo off väljastamist lausega
SETLOCAL, jäävad kõik
muudatused .bat faili piiridesse. Globaalsete keskkonnamuutujate väärtused
cmd.exe akna jaoks salvestatakse sellistena, nagu nad olid ja
pärast bat programmi töö lõppemist taastatakse endine
olukord. Kõik muutujad bat faili sees ja ka globaalsetesse
muutujatesse tehtud muudatused haihtuvad. Globaalsete muutujate
väärtused paistavad bat failile aga läbi. Sama asi jätkub
ka siis, kui .bat fail kutsub välja teise .bat faili või enda sees
peituva funktsiooni - SETLOCAL ja ENDLOCAL bat faili või funktsiooni
sees tagab, et muudatused jäävad selle .bat faili või funktsiooni
sisse.
See on väga hea asi programmeerimist natukenegi tundvale, sest kaitseb ühte programmi teise eest.
See on väga hea asi programmeerimist natukenegi tundvale, sest kaitseb ühte programmi teise eest.
Olgu minu programmis
muutuja count, mis loeb ära, mitu korda ma pean mingit
tsüklit tegema ja vahepeal välja kutsuma programmi B. Programmi B
kirjutaja võis kasutada sama muutujat mingi teise tsükli tegemiseks
ja sealt tagasi tulles on minu count ära muudetud.
Nüüd aga kirjutab ta oma programmi algusesse sisse SETLOCAL. Siis kui B vajab nüüd ka kas minu programmi, või üldise cmd akna muutujate muutmist, kirjutab ta ENDLOCAL, muudab need globaalid, mis vaja, ära, ja alustab jälle SETLOCAL sessiooni. Enne oma programmi lõppemist lõpetab ta programmi töö ENDLOCAL-ga.
Muutuja count muutmine tema programmis minu programmi ei mõjuta, ma võin välja kutsuda B-d palju tahan.
Kõikide ühiste muutujate muutmine peab olema muidugi omavahel viimseni kooskõlastatud, need on kohad, mis on kõrgendatud veariskiga...
Nüüd aga kirjutab ta oma programmi algusesse sisse SETLOCAL. Siis kui B vajab nüüd ka kas minu programmi, või üldise cmd akna muutujate muutmist, kirjutab ta ENDLOCAL, muudab need globaalid, mis vaja, ära, ja alustab jälle SETLOCAL sessiooni. Enne oma programmi lõppemist lõpetab ta programmi töö ENDLOCAL-ga.
Muutuja count muutmine tema programmis minu programmi ei mõjuta, ma võin välja kutsuda B-d palju tahan.
Kõikide ühiste muutujate muutmine peab olema muidugi omavahel viimseni kooskõlastatud, need on kohad, mis on kõrgendatud veariskiga...
Väljakutsuva programmi
muutujate muutmise eest ei ole kaitset väljakutsujal, sellega peab
tegelema funktsiooni või alamprogrammi kirjutaja. Kui ta seda ei
tee, on asjad pekis, s.t. B saab minu muutujad, kohtades, kus ta on unustanud SETLOCAL / ENDLOCAL-i, vussi keerata.
Kui B muudab midagi globaalse käsuakna keskkonnamuutujates, peab see kusagil
selgelt kirjas olema ja minu programmiga on täpselt sama lugu...
Niisiis alustage oma
bat faili käsuga pärast @echo off -i
SETLOCAL käsuga.
Alamprogrammid / failid
/ programmijupid, mida suure pingutusega võib kutsuda ka
funktsioonideks, s.t. mida kutsute välja CALL -iga ka teie faili
sees, ka seal peab kõik algama sama lausega SETLOCAL.
Alamprogrammist
väljudes peab olema lause ENDLOCAL.
bat failist väljudes
cmd.exe käsurea peale tagasi tehakse see automaatselt.
Aga nüüd tulevad
SETLOCAL käsule manukad, keda üldse vaja ei ole:
a) Laienduste
lubamine. Teie õnneks enamik moodsaid (isegi XP on moodne bat
failide mõttes) masinaid paneb cmd.exe käima nii, et laiendused on
nii ehk nii sees. Aga on üks väga paha asi - need laiendused saab
mingil viisil registris välja lülitada. Et teie poolt käivitataval
cmd.exe -l need ikkagi olemas oleksid, on kaval cmd.exe käima panna
/E:ON võtmega.
Aga programmide
kirjutaja peab arvestama igasuguse loomaaiaga issanda arvutipargis.
Mõnel arvutil võib see asi olla registris kuidagi disabled ja
seetõttu peab tema arvutis programm kindlasti alustama oma tööd
nii:
SETLOCAL
enableExtensions
/ suur väiketähed W-s
ei loe siin, aga KOHATI LOEVAD !! , aga mingit tüüpi
suur-väiketähtede kokkulepped oleksid hea asi. Saab paremini
programme lugeda.
Aga nüüd ei pruugi
kohtades, kus programmeerija tahab tõesti mõnda cmd.exe akna globaalmuutujat muuta, enam neid laiendeid saada kasutada. Nüüd peab .bat
keele õppija kohe kindlasti teadma, millised on laiendatud
võimalused ja millised võimalused (seejuures väga piiratud) on
need vanad võimalused, et mitte eksida nendes programmi
sektsioonides, kus ta peab tegelema globaalsete muutujatega, sest seal kehtib kitsendatud süntaks.
Seda lihtsalt seetõttu,
et kaks käsku on pandud ÜHTE PATTA.
Sellist omadust
kutsutakse mitteortogonaalsuseks.
b) Muutujate
muutmise lubamine.
Aga kus kaks vana sõpra
juba ees, las tulla kolmaski - omadus enableDelayedExpansion
võimaldab muutujaid kasutada ka nii, et ploki sees muutuja väärtused
tõesti ka muutuksid....
Aga sektsioonides, kus
tuleks muuta globaalseid muutujaid, ei saa te seda omadust
tingimatult jõustada .
Õnneks neid ei tohiks palju ette tulla, aga küsimus on ka natukene põhimõttes - miks peab 3 täiesti erinevat asja olema kokku keeratud ühte patta?
Õnneks neid ei tohiks palju ette tulla, aga küsimus on ka natukene põhimõttes - miks peab 3 täiesti erinevat asja olema kokku keeratud ühte patta?
Niisiis peate alustama
oma programmi tööd nii:
@ECHO OFF
SETLOCAL
enableExtensions enableDelayedExpansion
Nende tegevuste edukuse
kohta (peaks olema iga DOS käsuga enam-vähe nii) on leiutatud
suhteliselt ebaõnnestunud nimega muutuja ERRORLEVEL. See on siis, kui käsk
õnnestub, 0 ja kui ebaõnnestub, 0-st erinev, sisaldades veakoodi.
Selline natukene
äraspidine loogika kehtib ka Unix-is ja on õigupoolest pärit C
keelest. Ei saa seda just väga õnnestunud konstruktsiooniks lugeda,
C keele omapära tõttu on see C-s põhjendatud, aga ta on kandunud
ka mujale. Ometi saab sellega vähemalt teada, kas enableExtensions
õnnestus või mitte.
Enamasti ei viitsi .bat
programmeerijad sellega vaeva näha, ja õigusega - normaalsed
arvutitel peab see asi toimima ja kui ei toimi, ei ole seal mingite
asjade toimetamine eriti mõtekas. Las uurib oma IE 6.0-ga mingit
internetisaiti ja piisab sellestki ...
Aga isegi siis, kui
lause
SETLOCAL
enableExtensions enableDelayedExpansion
on jõus, ei muutu
protsendimärkidega tsüklites, ülaltoodud näited, mitte kui
midagi.
Et muutujat muuta,
peate muutuja sisule viitamisel kasutama kahte hüüumärki.
Ja programmi
sektsioonides, kus tahetakse muuta globaalseid muutujaid, ei saa te
sellist asja üldse kasutada!!
Ühesõnaga - pärast
neid settinguid käitub plokk
SET hei=hai &
echo !hei!
täiesti mõistlikult.
Saate vastuseks hai.
Sellega lugu siiski ei
piirdu. batil on varuks iga nurga peal krutskeid.
Proovige sellist plokki -
Proovige sellist plokki -
SET hei=hai &
echo !hei!!hei!
Saate
hai hai
Nüüd on vist selge,
miks on omistamisel vaja kirjutada
SET "hei=hai"
& echo !hei!!hei!
tuleb
haihai
nagu oligi mõeldud...
Programmis on nüüd
palju kohti, kus ühel ja samal muutujal on kaks erinevat
väärtust - ühe saab kätte %hei% -d kasutades, teise !hei!
-d kasutades.
Lisaks kõigele muule
lisab !hei! notatsioon erisümbolite ridadesse hüüumärgid
ja paneb isegi siis, kui muutuja hei sisaldab TÄPSELT samasid
märke nii ühte kui teisipidi vaadeldes, echo %hei% ja echo
!hei! erinevalt käituma.
Võimalik ainult
Venemaal ja MS-s!
III Põnev
probleem batmannidele - tühja rea väljastamine.
Ülesanne:
Väljastage bat/cmd failist hello ja
world vahele tühi rida.
Väga raske
ülesanne: teha seda ÜHE echo käsuga. (vt. IV sektsiooni selle
lahenduse osas).
Algajalik lihne echo
valmistab kohe üllatuse.
echo is off
või
echo is on
tuleb vastuseks. Sõltub
sellest, kas olete oma kaja välja lükanud või mitte.
Selgub aga, et tühja
rida võib väljastada päris mitmel viisil
näiteks
echo.
echo:
echo,
echo(
ja selgub näiteks, et
pärast
echo tere >echo
-t (tekitate faili echo ja kirjutate sinna tere)
echo. enam ei
toimi! Teile vastatakse endise viisaka reavahetuse asemel nipsakalt:
'echo.' is not
recognized as an internal or external command,
operable program or
batch file.
Väidetavalt echo(
ainukesena ei pidavat tekitama jamasid ... aga te kohtate päris
sagedasti echo. konstruktsiooni, või echo/
konstruktsiooni. Ja ei ole viitsinud uurida, mis siis echo/
-ga näiteks lahti on.
Nii et lahenduseks
oleks
echo hello &
echo( & echo world
vt <13>
IV Täiesti
erilised erimärgid ja tühja rea väljastamise erimuutuja.
Bat olukord
pärast enableDelayedExpansion-i elluviimist sümbolite osas
on siiski paranenud. Enne seda oli asi päris hull. Praegu, ette
teades, et erisümbolitega võib tulla jamasid, on siiski võimalik
nendega toime saada.
See, et echo %hei%
ja echo !hei! käituvad erinevalt, on pigem hea kui halb. Ja
enamasti see, mis
echo %hei% teeb,
ei ole hea ja echo !hei! väljastab täpselt muutuja hei
sisu, kõigi seal sisalduvate sümbolitega. Eriprobleemiks
on aga need sümbolid sinna muutujasse saada.
Näide probleemidest %xxx% notatsiooniga:
Tippige
Tippige
set "hei=hello
& world" .
(siin set "xxx=zzz
zzz" võimaldab muutujale xxx sisse smugeldada
erimärke)
Nüüd echo %hei%
annab juba tuntud vea, sest & järel tahab täitma hakata
järgmist käsku
echo !hei! saab
hei sisu avaldamisega ilusti hakkama, sest ei interpreteeri !hei!
stringi mitte mingil moel.
Nii et kasutage !xx!
notatsiooni
Erisümbolite
sissesmugeldamine muutujasse aga ei ole alati lihtne. Toon näiteks
reavahetuse NL tekitamise:
Muudes keeltes on vaja
õigele kohale kirjutada \n ja see toimib kui reavahetus ...
Bat keeles on asi
keeruline.
Aga saab.
Selleks peate kirjutama
set LF=^
REM need
reavahetused on vajalikud
Nüüd
echo hei!LF!hei
annab
hei
hei
^ sümbolil on kaks tähendust: kõigepealt on ta paosümbol -
^ abiga võite pääseda sümbolite > < & ...
eritähendustest
Näiteks echo hallo
^& world
annab
hallo & world
Aga samal sümbolil on
kahjuks/õnneks ka teine funktsioon – pikkade ridade pikendamise
võimalus.
järgnevat reavahetust
lihtsalt ignoreeritakse.
Tippige ntx faili
reapikendus.cmd sisse
@ECHO OFF
::SETLOCAL
EnableExtensions EnableDelayedExpansion
set hei=hello^
& world
echo
Protsendimargiga hei: %hei%
echo Hyyumargiga
hei: !hei!
^ siin teeb ühekorraga
kahte tööd – märgib ära, et kui tema järel tuleb reavahetuse
sümbol, siis me selle jätame tähelepanuta, ning seejärel
jätame erikohtlemiseta iga järgneva sümboli (praegu siis &,
aga
reavahetuse
muutuja loomise näites reavahetuse sümboli enese.
Nii näiteks
echo hei^
>NUL
väljastab hei>NUL
Üritasin
illustreerida, et > on väljundi ümbersuunamise sümbol
ja ülal üritati väljundit 2 rea peal suunata ümber ei kuhugi
(tobedatel illustratiivsetel eesmärkidel, juhendite kirjutajate
armastatuim tegevus – välja mõelda tobedusi: tahan öelda echo
hei ja seda nii, et keegi ei näeks)
< suunab samal
eesmärgil ümber sisendi.
Ja ^ päästab selle
märgi eritähenduse eest, käsitledes <, > ... j.t. erimärke
tavasümbolitena.
See ei toimi alati –
kui kirjutada, nagu ma olen õpetanud set käsku tegema sama
asja NII:
set "hei=hello^
>NUL"
saate nende ridade
täitmisel veateate koos exit /B 1 /ga (väljumise käsk .bat
failis vea korral, väljund 0 tähendab et kõik korras)
The syntax of the
command is incorrect.
Reavahetust ei
ignoreerita, set käsk täidetakse, järgmine rida on uus
käsk, >NUL annab mõttetuse.
Teada kiiks ^ puhul:
% märgi
eritähendust ^ millegipärast ei mõjuta. selle asemel tuleks
% märk kirjutada TOPELT.
^ mõjutas %
märki küll cmd.exe käsureal, aga bat faili sees kirjutati ^%hei^%
asemele tühi väärtus, ja lubatud sümbolite joru %hei% ekraanile
ei tulnud. Otsitakse taga hoopis imelikku muutujat hei^,
mis on tühi.
Sarnase .bat tujutsemise tõttu tuleb iga väidet/konstruktsiooni kontrollida - võib juhtuda, et olete esimene, kes avastab, et see näiteks teie arvutil ei toimi ja tuleb leida teine tee...
Sarnase .bat tujutsemise tõttu tuleb iga väidet/konstruktsiooni kontrollida - võib juhtuda, et olete esimene, kes avastab, et see näiteks teie arvutil ei toimi ja tuleb leida teine tee...
Kuidas kasutaja
erimärke sisestada võiks:
Kasutajatele andmete
sisestamiseks on olemas käsk
set /p
hallo=sisestage siia midagi:
siin hallo on
muutuja nimi, = märgi järel olev tekst on kasutajale
ettetulev prompt.
Võib-olla polegi
erisümbolitega asi väga hull, kui võrrelda lausa skandaalse
olukorraga, mida näete sektsioonis X - kõige lihtsamad
sõneoperatsioonid tekitavad programmeerijale märkimisväärset
peavalu - näiteks suurtähtedeks teisendamine, stringi pikkuse
leidmine (see fakt on absoluutselt skandaalne), tavaline joondamine
etc...
Aga ka täiesti tavaline võrdlemine toob kaasa üllatusi. Sellega sektsioonis V tegelemegi.
Aga ka täiesti tavaline võrdlemine toob kaasa üllatusi. Sellega sektsioonis V tegelemegi.
V Täiesti
erilised kolmetähelised nimetused tingimuste kontrollil - Suurima
üllatuse printsiip!
Peaaegu kõik
programmeerimiskeeled tavaliselt võrdlevad oma asju ühtemoodi -
nagu matemaatikas ammu välja kujunenud on, <, >
ja = märke kasutades.
= märk on
programeerimises matemaatikalt ära võetud - see on jäetud
omistamisele, seetõttu seda asendab ==
kaks võrdusmärki
koos. Nii on tavaline käibiv komplekt võrdlusteks
märgid ==,
>=, >, <, <=
ja != (ei ole võrdne).
Lisaks nendele kasutas näiteks Larry Wall perlis tähiseid lt (less than), gt (greater than), eq (equal), ne (not equal) sõnede võrdlemiseks ja tal oli selleks ka põhjus. Nimelt skriptivates keeltes ei ole tüüpe ja programeerija hooleks on teada, mida ta üldse võrdleb - sõnesid või arve. Vahel mõnes keeles (näiteks JavaScript) tikub programmeerimiskeel liiga tark olema ja enne võrdlust ühte tüüpi andmeid teiseks teisendama, tekitades raskesti avastatavaid vigu...
Lisaks nendele kasutas näiteks Larry Wall perlis tähiseid lt (less than), gt (greater than), eq (equal), ne (not equal) sõnede võrdlemiseks ja tal oli selleks ka põhjus. Nimelt skriptivates keeltes ei ole tüüpe ja programeerija hooleks on teada, mida ta üldse võrdleb - sõnesid või arve. Vahel mõnes keeles (näiteks JavaScript) tikub programmeerimiskeel liiga tark olema ja enne võrdlust ühte tüüpi andmeid teiseks teisendama, tekitades raskesti avastatavaid vigu...
Nii et lt, gt,
eq komplekti esinemine teist tüüpi võrdluseks on
õigustatud. Perlis numbreid võrreldakse nagu matemaatikas, stringe
aga gt, lt, eq ... abiga.
Meie BAT ei tee ei ühte
ega teist. Ta võrdleb oma tarkusega (ise teab, kas ta arvab tegemist
olevat arvude või sõnede võrdlusega) kahte operandi ja kasutab
nendeks absoluutselt üllatavalt, KOLMANDAT, unikaalset (vt.
erinevate keelte võrdlusoperaatoreid <18>
) tähistusviisi, nimelt operaatoreid lühenditega
EQU, NEQ, GTR, LSS,
GEQ, LEQ.
Tähendused:
EQU - võrdne
NEQ - ei ole võrdne
GTR - suurem kui
LSS - väiksem kui
GEQ - suurem või
võrdne
LEQ - väiksem või
võrdne
Ma nimetaksin seda
Suurima Üllatuse
Printsiibiks
analoogina Rubys
käibivale "Vähima Üllatuse Printsiibile" <19>
Kuid tööd teha
saab. Kuigi ruttan ette - tsüklist kohe allpool, saab IF võrdlust
kasutades sellise progejupi kirja panna, mis täisruute väljastab
btw võta töötav
jupp...
set count=0
:ruudud
if !count! LSS 10 (
set /A
countruudus=!count!*!count!
echo "Arvu
!count! ruut on !countruudus! !"
set /A count+=1
goto :ruudud
) else (
echo "Ruudud
arvutatud!"
)
pause >NUL
Pause peatab
programmi töö, oodates klahvivajutust. Muidu teatest press any
key lahti ei saa,
kui suunata see NUL-i,
enne seda peate echo-tama teate, mida tegelikult tahate kasutajale
öelda...
VI Värdnimedega
muutujate lubamisest
Kunagi oli NL-s
väga populaarne laul teemal et ma teist niisugust maad ei teagi, kus
nii vabalt hingab inimene....
Ma ei tea ühtegi teist
skriptimiskeelt (kes teab, andke märku!), kus nii vabalt saab
meisterdada muutujaid. Seda peaaegu ükskõik milliste
nimedega. Loome näiteks muutujad nimedega ‘.’,
‘:’,
‘.
‘ – lugesite õieti – punkt ja kaks tühikut. Kõik on
võimalik! Ei usu?
c:\bat>set
".=PUNKT"
c:\bat>set
",=KOMA"
c:\bat>set
":=KOOLON "
c:\bat>set
"==VORDSUS"
The
syntax of the command is incorrect.
c:\bat>set
". =PUNKT JA KAKS TYHIKUT"
Ja
vaatame oma loomaaia käsuga SET üle:
,=KOMA
.=PUNKT
.
=PUNKT JA KAKS TYHIKUT
:=KOOLON
Ainult
võrdsusmärki ei õnnestu muutujaks defineerida, aga ma ei
ole kindel, kas seegi ei võiks kuidagi läbi minna...
Ma
ei tea ka mitte ühtegi mõistlikku põhjust sellise anarhia
lubamiseks peale selle, et oleks huvitavam ja lõbusam, nagu NL-s
oligi.
Mõnikord
lihtsalt mõni asi ei klapi. Näiteks käsurea peal saab meisterdada
muutujaid %1, ...%9.
.bat
skripti sees hästi ei saa (mul ei tulnud välja, aga mine tea, äkki
kellelgi tuleb)...
Kui
pea tööle panna, saab nii genereerida väga absurdseid vigu ja
programmi väga absurdselt käima tõmmata. Häkkerite paradiis ja
normaalsete programmeerijate õudusunenägu.
Normaalsed
keeled, nagu Perl, piiritlevad selle mängumuru väga selgelt.
Alakriips, ladina tähed, numbrid, aga mitte mingil juhul ei tohi
muutuja alata numbriga.
.bat-s
pole probleemi.
c:\bat>set
5=25
c:\bat>set
5
5=25
...
ja nii edasi ja nii
edasi, nagu Vonnegut armastas kirjutada ...
VII Kuidas
kommenteerida .bat faile.
Ma ei tea
ühtegi teist programmeerimiskeelt peale .bat keele, kus
ametlik kommentaaririda
võib põhjustada
ametliku veateate.
Kirjutage selline
programm:
@echo off
echo hei
REM See kommentaar
on vigane! %~...
echo see oli vigane
kommentaar, mistqttu programm siia ei jqudnud !
Saate vastuseks
omapärase tiraadi:
hei
The following usage
of the path operator in batch-parameter
substitution is
invalid: %~...
For valid formats
type CALL /? or FOR /?
Kaotage need õnnetud
%~ ... tiraad kaob:
hei
see oli vigane
kommentaar, mistqttu programm siia ei jqudnud
REM ei ole pigem
kommentaar, vaid nagu käsk, mis ei tee midagi. Nii saab mõne teise
käsuga koos
moodustada plokke, kus
&REM järel tulev jutt paistab nagu realõpukommentaarina.
echo hei &REM
siia saab ka kommentaarida...
Kui echo on
sisse lülitatud, siis REM tekst paisatakse ekraanile ja kui
väljund on ümber suunatud, siis kuhugi faili. Seetõttu võib seda
koguni kasutada millegi kirjutamiseks faili, nagu käsku.
Nii tavaliselt ei tehta
- kasutada kommentaari käsuna. bashis on olemas nii mittemidagi
tegemise käsk ja kommentaarimärk ( : ning #
).
Unix-is on deviis, teha
ühte asja ja teha seda hästi. Kuna REM tahab teha mitut asja, s.h.
mittemidagitegemise käsku, siis ei tee ta mõlemat hästi.
REM on aeglane,
võrreldes REM asendamiseks väljamõeldud häkiga ::
See häkk põhineb
sellel, et : -ga algavad märgendid (label) ja kaks koolonit on
selline vigane märgend, kuu GOTO kunagi ei saa jõuda ja sinna saab
igasuguseid asju kirjutada lõppu.
Üldse saab märgendite
taha kirjutada juttu juurde, niisiis ka :: taha.
Et kahe kooloniga
kommentaarid jooksevad kiiremini kui REM kommentaarid on järjekordne
programmeerimisalane huumor, aga nii on.
Ka :: ei päästa %~
-le järgneva tiraadi eest, võite proovida.
:: -l on veel üks häda
– käsuplokkide sees põhjustab veateateid.
Võib-olla on kõige
lihtsam lugeja elu veidi keerulisemaks teha ja kommentaarid asetada
käsuplokkide ette või taha, seal ei tohiks palju probleeme olla –
või siis ikkagi käsuplokkide sees kasutada neid REM-e, kui muidu ei
saa.
:: näevad välja
ilusamad. Nii arvavad paljud DOS häkkerid.
VIII Vältimatu
GOTO, hoolimata Dijkstrast – tsüklid ja funktsioonid
Tänapäeva
moodsates keeltes enam GOTO-d ei ole, põhjuseks Dijkstra
artikkel <17>.
GOTO on aga alati
olemas olnud ja jääb alati assemblerikeelte raudvarasse koos
alamprogrammi väljakutsumise käsuga CALL, mille lõpetab
return käsk, mis viib alamprogrammist tagasi CALL-le järgneva
assemblerirea peale.
Protsessor lihtsalt
masinakäskude tasemel muust ei ole võimeline aru saama.
Selles mõttes .bat
keel on assemblerilähedane. Lisaks on olemas for tsükkel,
aga väga iseäralik – teiste keelte for tsüklite tundmine
ei aita, vaid hoopis segab selle omapärase käsu uurimisel.
Funktsioone ei ole,
seda asendab CALL :label, nagu assembleriski.
For tsüklite
“omapärade” tõttu ei ole alati võimalik kõiki tsükleid for
abiga teha ja peabki selgeks õppima klassikaliste assembleristide
tavarelvastuse.
Kuidas .bat-s (ja
assembleris) tsüklit teha
Tippige (ntx faili
sum100.cmd)
@ECHO OFF
SETLOCAL
enableExtensions enableDelayedExpansion
set /A i=1
set /A sum=0
:LOOP
SET /A sum+=i
SET /A i+=1
IF !i! LEQ 100 GOTO
:LOOP
echo Arvude summa
1..100 on !sum!
pause >NUL
Peate saama:
Arvude summa 1..100
on 5050
Noor Gauss põhjustanud
selle summa momentaalse arvutamisega oma matemaatika õpetajale palju
meelehärmi, sest see tahtis lapsed pikemalt tööle panna.
SET /A (aritmeetika)
valik võimaldab muutujatel esineda ka oma nime all, ilma ! ! või %
% ümbriseta, % % ümbris või ! ! ümbris on endiselt võimalik ja
selles tsüklis võib mõlemat kasutada, for tsüklis näiteks enam
mitte, vaid ainult ! ! ümbrist, sest % ümbrise väärtused ei muutu
rohkem kui 1 kord...
Funktsioonilaadse
objekti tegemise näiteid .bat –s.
Tippige (ntx faili
sumA_B.cmd)
@ECHO OFF
SETLOCAL
enableExtensions enableDelayedExpansion
SET A=1000000000
SET B=1000000000
:: programm arvutab
A ja B summa 2-l erineval viisil.
CALL :sumABvigane
%A% %B%
ECHO sum on nyyd
%sum%
set sum=0
CALL :sumABlocal %A%
%B%
ECHO sum on nyyd
%sum%
:: EXIT kindlasti
enne funktsioonide tulekut, muidu saate imelikke veateateid...
EXIT /B
:: Funktsioonide
plokk siia programmi peakood ei tohi sattuda.
:sumABvigane A B --
globaalsesse muutujasse sum kirjutatakse A ja B summa.
:: siin on meelega
sisse kirjutatud kood, mis muudab globaalseid muutujaid A ja B
SET A=%1
SET B=%2
:: %A% %B% / !A!
!B! asemel saab set /A -sse kirjutada A ja B
SET /A sum=A + B
:: GOTO :EOF on
synononyym EXIT /B 0 -le. 0 ei ole vajalik, EXIT /B –st ka piisab.
GOTO :EOF
:sumABlocal
SETLOCAL
SET A=%1
SET B=%2
set /A sum=A + B
ENDLOCAL & SET
sum=%sum%
EXIT /B
Programmi käivitusel
saate 2 korda summa A ja B,
(seda kontrolliks, et
olete asjad õieti tippinud /pasteerinud).
Siin saate ka pärast
eksperimenteerida aritmeetika limiitidega - pange näiteks
A=2000000000 ja B=3000000000, siis hakkavad tulema jaburad tulemused
- õige vahemik, kus .bat aritmeetika kehtib, on W XP-st alates
−2147483648
... 2147483647 ja 2000 ja madalamad masinad
tunnistavad ainult positiivseid arve, seda vahemikus 0
.. 4,294,967,295.
Koodi uurimine:
A: F-ni
väljakutsumine
Rida
CALL :sumABvigane
%A% %B%
kutsub välja samas
failis oleva funktsiooni sumABvigane
Teisi .bat faile
saab ka välja kutsuda, siis :xxx asemel on vaja selle faili nime
(samas kataloogis) või pikka teed selle faili juurde ilma koolonita.
Teistes .bat
failides olevaid funktsioone ei saa nii välja kutsuda. Muidugi saab
selle .bat faili ette ehitada mingi erilise
analüsaatori, mis siis CALL järele kirjutatud mingist
eriparameetrist (ütleme esimene parameeter) loeb välja, mis
FUNKTSIOONI tegelikult taheti saada.
Ma siiralt loodan, et
pääsete enne .bat palatist ja ei hakka selliseid
imelikke asju välja mõtlema...
CALL xxx järele
saab kirjutada igasuguseid parameetreid. %A% ja %B% panevad nendeks
parameetriteks
muutujate A ja B
väärtused.
!A! ja !B! oleks isegi
ohutum, aga praegu ei puhu see pilli.
Kui te oleks kirjutanud
CALL :sumABvigane A B
oleks te funktsioonile
üle andnud muutujate A ja B nimed.
Seda tehke ainult
siis, kui tahate tagasi saada muutujatesse mingeid väärtusi
funktsioonilt. Praegu me nii ei tee, me oleme kokku leppinud, et
tagastatakse väärtus muutujasse sum.
Me ei ole aga kokku
leppinud, et funktsiooni sumABvigane programmeerija hakkab
laamendama globaalses nimeruumis ja kirjutab üle või tekitab seal
mingid suvalised muutujad A ja B.
(Võib aga juhtuda, et
programmeerija oli hajameelne ja unustas mõned tähtsad read ära.
Millised, kohe allpool)
sumABvigane
väärtuste üleandmise korral %% märkide abiga kogemata töötab
nii, et ei tee kahju isegi ülemprogrammile.
Globaalne muutuja A
saab oma väärtuseks üleantud A väärtuse %A%, s.t. jääb samaks
ja B saab oma uueks väärtuseks väärtuse %B%. Seejärel
arvutatakse summa ja kõik töötab laitmatult.
Kui sumA_B
programmeerija oleks kirjutanud programmi väljakutsumisel %A% ja %B%
asemele A ja B, oleks funktsioon sumABvigane globaalsete
muutujate A ja B väärtuseks saanud tähed A ja B.
SET /A sum=A
+ B oleks asendanud, nagu ennegi A
tema väärtusega A, enne oleks seal olnud 1000000000, ja B
tema väärtusega B (enne 1000000000).
Aritmeetika korral on
kõik sõned võrdsed 0-ga, tulemuseks oleks tulnud 0.
Vastus oleks tulnud
õige, kui summa arvutamise funktsiooni programmeerija ei oleks
tegelenud parameetrite ümberomistusega oma muutujatesse ja oleks
kohe kirjutanud
set /A sum=%1
+ %2
%1
väärtus oleks olnud küll A, aga A väärtuseks oleks leitud
globaalsest nimeruumist 1000000000
ja B väärtuseks
analoogiliselt 1000000000.
Nii ei ole siiski õige
teha. Parameetritega otsemanipuleerimise asemel oleks ohutum nad
siiski ümber kirjutada LOKAALSETEKS muutujateks.
(pseudo)lokaalseteks
täpsemini, aga tühja sellest.
Õige viis funktsiooni
sees õiendmiseks on toodud funktsioonis
sumABlocal
Muutujatega A ja B
toimunud ei mõjuta väljakutsuja funktsioonis muutujate A ja B
väärtusi, nende väärtused taastatakse ENDLOCAL käsule
järgnevas plokis.
Kuidas aga
informatsiooni funktsiooni seest tagasi saada?
Selleks tehakse selline
trikk - paneme ENDLOCAL-iga samasse plokki veel lauseid. Kuna veel ei
ole SET endine komplekt muutujaid taastatud, kehtivad kõik SETLOCAL
sees olevate muutujate väärtused. Omistuse sum=
puhul aga otsitakse üles juba sum globaalne muutuja (või luuakse)
ja
nii omandabki sum=%sum%
mõtte – globaalne sum saab lokaalselt ümberarvutatud sum
väärtuse.
Mingil imelikul viisil
pärast muutujakomplekti taastamist jääb see jõusse.
Seda jama kutsutakse
veel tunneldamiseks ja mingit mõistlikku pikka selgitust ma leidnud
ei ole.
Ehk leiab selle
raamatust <0>
B: Väärtuste
tagastamine funktsioonist väljundmuutujate kaudu
%0, %1 … ei
ole muutujad erinevalt näiteks Perlist ja teistest keeltest, kus
käsuparameetreid käsitletakse täpselt samade grammatikareeglite
järgi, kui teisi muutujaid. See fakt teeb ettevaatlikuks, ei tasu
neid muutujaid manipuleerida, ilma, et täpselt teaksite, mis toimub.
%0 on väljakutsutava
.bat/cmd faili nimi. %1 , %2 … on väljakutsumise rea pealt
üleskorjatud parameetrid, nagu cmd oskas neid tõlgendada...
Kui lugeda funktsioonis või .bat/cmd programmis %1 ...%9 väärtusi, saab tõesti need sõned, võimalike modifikatsioonidega, mida on funktsiooni väljakutsumisele reale antud.
Kui lugeda funktsioonis või .bat/cmd programmis %1 ...%9 väärtusi, saab tõesti need sõned, võimalike modifikatsioonidega, mida on funktsiooni väljakutsumisele reale antud.
Aga mis saab siis, kui
teha omistusi stiilis
%x=mingi väärtus
Toon ühe mõtlemapaneva
testprogrammi:
@ECHO OFF
SETLOCAL
enableExtensions enableDelayedExpansion
:: programm uurib %1
ja %2 omistuste tulemeid alamprogrammi sees
set "hello=hallo"
set "world=maailm"
Call :helloworld
hello world
echo hellost sai
%hello%
echo worldist sai
%world%
echo Nyyd
arvuparameetrid
PAUSE
Call :helloworld 4 3
echo 4 on !4! ja 3
on !3!
PAUSE
Call :helloworld %3
%4 yks kaks
echo yks on !yks! ja
kaks on !kaks!
pause >NUL
EXIT /B
:: functions block.
:helloworld
::SETLOCAL
echo %1 %2
set "%1=ai"
set "%2=oi"
echo %1 %2
::ENDLOCAL
GOTO :EOF
Väljund:
hello world
hello world
hellost sai ai
worldist sai oi
Nyyd arvuparameetrid
Press any key to
continue . . .
4 3
4 3
4 on ai ja 3 on oi
Press any key to
continue . . .
yks kaks
yks kaks
yks on ai ja kaks on
oi
Selgitusena.
Programmeerija Juku
pidi väljastama paar sõnumit ekraanile. Esimene sõnum tuli
parameetritest ja teine sõnumi jaoks ta ei tahtnud muutujaid
raisata, ka SETLOCAL ja ENDLOCAL jäävad nii ära –
muutujateks on %1 ja
%2.
Kahjuks programm
väljastas kaks korda täpselt sama sõnumi, omistused
set %1=ai ja
set %2=oi ei mõjunud kuidagi.
Peaprogrammis aga
avastati, et muutuja hello väärtusest hallo (tõlge eesti keelde)
oli saanud ai ja world-st oi (pidi olema maailm). Teises väljakutses
olid tekkinud imelikud numbrilised muutujad
number 4 nimeline
muutuja oli ai ja 3 oli oi.
Kolmanda väljakutse
tegi üks häkker, kes üritas sellega selgeks teha, milles viga on.
Jukul tuli programm
ümber teha, kirjutada oma tekst SETLOCAL ja ENDLOCAL vahele ning
kasutada oma muutujaid ning lisaks selgeks teha, milleks on omistused
%1= ja %2=
Vasakul pool
omistus/võrdusmärki on %1 ja %2 viited kas juba olemasolevatele
muutujatele, või need luuakse selle omistuse käigus. SETLOCAL
ENDLOCAL vahel olev tegevus väljakutsuvasse programmi ei jõua, küll
võivad tekkida jaburad süntaksivead...
Kuna muutujate nimede
suhtes on .bat-s absoluutne vabadus, siis juhtub seda küllalt
harva.
Omistusi %y=xxx tasub
teha enamasti vaid väärtuste tagastamisel, ENDLOCAL-st
väljas, aga selle käsuga samas plokis olles.
Enne tasuks ehk
kontrollida, kas väljakutsuja muutujanimi vastab skriptivates
keeltes väljakujunenud standarditele ning muidugi ei ole tühi.
Väiksemates programmijuppides ehk ei ole vaja nii paranoiline
olla...
Nii võiks välja näha
sumA_Bref.cmd, kus väljakutsuja programm määrab, mis
muutujasse tulemus kirjutada:
@ECHO OFF
SETLOCAL
enableExtensions enableDelayedExpansion
SET A=1000000000
SET B=1000000000
ECHO Programm %0
arvutab muutuja nime edasiandmise viisil funktsioonile
ECHO arvude %A% ja
%B% summat!
set sum=0
CALL :sumAB %A%
%B% tagasi
ECHO Summaks sai
%tagasi%
pause
exit /B 0
:: Funktsioonide
plokk
:sumAB A B tagasi --
Arvutab muutujate A B summa ja tagastab summa väärtuse
:: muutujaviitesse
%3.
SETLOCAL
SET /A sum=%1 + %2
ENDLOCAL & SET
%3=%sum%
GOTO :EOF
C: Sisendinfo
kättesaamine muutujaviidete kasutamise korral.
On võimalik, et
mõnikord ei ole informatsiooni üleandmiseks alamprogrammile muud
head meetodit, kui muutujanime üleandmine. Sel juhul on vaja
lahendada omaette probleem - saada kätte muutujanime taga peituv
informatsioon.
Näide:
@ECHO OFF
SETLOCAL
enableExtensions enableDelayedExpansion
:: programm uurib %1
nime ja va"a"rtuse ka""ttesaamist funktsioonis
valByRef
:: pole mahti
tegelda ta"pita"htedega, sellest vo~imalik, et hiljem.
utf-8 ei toimi cmd.exe-s ha"sti.
set tagasi=65537
&REM Fermat viies ja viimane Fermat algarv, nagu arvatakse.
Call :valByRef
tagasi
PAUSE >NUL
EXIT /B
:: functions block.
:valByRef
SETLOCAL
set muutujanimi=%1
set
muutujaval=!%muutujanimi%!
echo muutujanimi on
%muutujanimi% ja muutuja va"a"rtus on %muutujaval%
ENDLOCAL
GOTO :EOF
Ühesõnaga, muutuja
taga peituva muutujanime tegeliku väärtuse saab kätte !%
kombinatsiooniga.
Tulemus:
muutujanimi on
tagasi ja muutuja va"a"rtus on 65537
D: EXIT kasutamine
funktsiooni tulemuse tagastusel
EXIT /B –le saab
lisada ka numbrilise tagastusväärtuse, mida väljakutsuja saab
lugeda
ERRORLEVEL nimelisest
muutujast.
Seda saaab kasutada
vaid numbriliste arvutuste puhul.
Selleks tuleks
ülaltoodud programmis asendada read
CALL :sumAB %A%
%B% tagasi
ECHO Summaks sai
%tagasi%
ridadega
CALL :sumAB %A% %B%
ECHO Summaks sai
%ERRORLEVEL%
ning funktsioonis
:sumAB ENDLOCAL plokk käsureaga
ENDLOCAL & EXIT
/B %sum%
IX FOR veidruste
anatoomia
Kes vähegi tahab .bat
keeles tegija olla, peab ära õppima .bat ainukese korralik olla
tahtva tsüklikonstruktsiooni nimega FOR. Kui muidugi
assemblerilaadne GOTO välja arvata.
Kahjuks GOTO
konstruktsiooniga tsükkel on korralik ja FOR konstruktsioonid ei
ole.
Muutujatest, mis % % vahele panduna ei muutu (ja lõpuks ! ! vahel muutuvad, sai juba räägitud.
Nüüd on aeg uuteks üllatusteks.
Muutujatest, mis % % vahele panduna ei muutu (ja lõpuks ! ! vahel muutuvad, sai juba räägitud.
Nüüd on aeg uuteks üllatusteks.
Alustame grammatikast:
For
cmd.exe käsurea pealt sisestatuna:
FOR
<
/D /R /F /L> %tsüklimuutuja
in (failid/fail/käsu tulem/muutuja) do (
in (failid/fail/käsu tulem/muutuja) do (
käsud
)
)
Märkus:
do (
)
asemel võib olla ka do
<üks käsk> või ka mitu käsku plokis &, &&,
|| abil ühendatuna (mis teeb ka ploki). && ja ||
kohta vt. allpool.
For .bat faili
sees - ainuke erinevus - %tsüklimuutuja asemel on nüüd %%
tsüklimuutuja -
FOR
<
/D /R /F /L>
% %tsüklimuutuja
in (set/file/commands) do (
in (set/file/commands) do (
käsud
)
)
Tsüklimuutuja tahab
omaette käsitlust. See on jälle uus objekt ja erinev nii muutujast
kui ka parameetritest. Parameetritega on tsüklimuutuja natuke nagu
sugulane, kuna tsüklimuutujaga saab teha samasuguseid teisendusi,
mis parameetritega, v.a. viited.
Tsüklimuutuja saab olla vaid üks täht / sümbol järgmistest ASCII sümbolite reast:
Tsüklimuutuja saab olla vaid üks täht / sümbol järgmistest ASCII sümbolite reast:
ASCII
63 - 93 - 31 võimalust
?
@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ]
ASCII 95-123 29 võimalust :_ ` a b c d e f g h i j k l m n o p q r s t u v w x y z {
ASCII 95-123 29 võimalust :_ ` a b c d e f g h i j k l m n o p q r s t u v w x y z {
Milleks
tsüklimuutuja %%{ hea on??
Ilmselt tunneb ta
ennast hästi teiste samasuguste värdmuutujate keskel...
Miks tavaline
muutuja ei kõlba?
Miks käsurea peal
kasutatakse ühte tähistust ja .bat failis teist?
Miks nii palju
erilisi tsüklimuutujaid üldse vaja on?
Rohkem kui ühte
tsüklimuutujat läheb vaja vaid FOR /F võtme puhul, mis
võtab oma sisendist (mingi fail, aga ka mingi käsk, võib - olla
koguni muutuja) ühe rea korraga ja jagab selle juppideks.
Mulle ei meeldi sõna
jupp, aga midagi paremat ei oska ka pakkuda termini token
kohta.
FOR /F ei saa
jagu rohkemast kui 31 jupist, hoolimata sellest, et tegelikult on ju
60 võimalust ette nähtud. Siis tuleb teha mitut FOR-i ja neid
kuidagi kombineerida...
Tsüklimuutujad on
muuseas globaalsed - tsüklimuutuja järgmise sisemise FOR sees näeb
välimise FOR tsüklimuutujat ...
Kui aga meil on mingi
.CSV fail, kus näiteks 100 veergu ja tahame seda faili
teisendada?
Äkki oleks tulnud FOR alla toppimise asemel leiutada mingi vahend, mis selliste failide analüüsiga paremini hakkama saab?
Kuid kõigest järjekorras ja alustame lihtsaimast FOR tsüklist, ainukesest arhaismist, mis jookseb ka siis, kui laiendid (extensions) on lülitatud välja.
Äkki oleks tulnud FOR alla toppimise asemel leiutada mingi vahend, mis selliste failide analüüsiga paremini hakkama saab?
Kuid kõigest järjekorras ja alustame lihtsaimast FOR tsüklist, ainukesest arhaismist, mis jookseb ka siis, kui laiendid (extensions) on lülitatud välja.
Selle FOR käsu
grammatika on järgmine:
FOR %% IN (loend1 loend2 loend3 ...) DO
Näiteks selline käsk
(käsurealt ühe % -ga!)
.bat-s
FOR %%a IN (1 2 3 4)
DO echo %%a
käsureal:
FOR %a IN (1 2 3 4)
@echo %a
Käsureal on vajalik ka
@ märk echo ees, mis echo maha võtab selle käsu
jaoks, et üleliigset spämmi vältida väljundis.
Hiilgav - tõesti
töötav käsk .bat keeles. Jälle üllatus (Suurima Üllatuse
Printsiip).
Tegelikult on IN käsk mõeldud toimima failinimede loendina või mallide loendina.
Tegelikult on IN käsk mõeldud toimima failinimede loendina või mallide loendina.
Näiteks:
FOR %a IN (pakk*.*
*.cmd) DO @echo %a
Sain oma arvutis bat
kataloogis uurimustöö teemale vastavalt joru pakkfailidx.x
failinimetusi (selle dokumendi erinevad versioonid erinevates
editorides ja kõik harjutuseks tehtud *.cmd failide
loetelu.
FOR /L tsükkel,
kus ei saadagi tsüklist välja.
Tippige
sisse selline fail (minul forever1.cmd), kus kõik toimib
normaalselt.
@ECHO %echooff%
SETLOCAL
enableExtensions enableDelayedExpansion
FOR %%a IN (1 2 3 4
5) do (
echo %%a
IF %%a EQU 3 GOTO
:break
)
:break
ECHO Saime minema!
PAUSE >NUL
EXIT /B 0
Selle tähelepanuväärse
vaimusünnitise eesmärgiks on demonstreerida toimivat
koodi.
.bat
tsüklikonstruktsioonides puuduvad break ja next
laused, mis tsüklist välja viivad või järgmisse
fataalsesse ahelasse
tagasi paiskavad.
Aga .bat ei ole kõrgkeel - siin on kahjulikuks kuulutatud, aga siiski toimekas GOTO, mis ka tsüklisse sattunu ravimiseks võiks kõlvata.
Aga .bat ei ole kõrgkeel - siin on kahjulikuks kuulutatud, aga siiski toimekas GOTO, mis ka tsüklisse sattunu ravimiseks võiks kõlvata.
Iga esmakursuslane
mõtleb ka välja, et siin käiakse läbi arvud 1..3 ja siis
tuleb tsüklikatkestus ja rohkem tsükliga jamamist ei ole. Ja iga
normaalne lugeja mõtleb nüüd seda lugedes, et milleks seda kräppi
siin mulle pähe määritakse. On kood, toimib ja milles probleem??
For /L tsükliga
nii ei ole.
Selle tsükli üldine
kuju on järgmine:
FOR /L %%tähtmuutuja IN (algus,samm,lqpp) DO
tähtmuutuja käib läbi väärtused algus, algus+samm,
.... kuni algus+ N*samm saab suuremaks kui lqpp,
väärtus lqpp käiakse ka läbi, kui alguse ja sammuga hästi
välja tuleb...
Tippige nüüd sisse järgmine kood (minul forever2.cmd)
@SET echooff=%~2
@SETLOCAL
enableExtensions enableDelayedExpansion
@(SET "echooff"
1>NUL 2>NUL)||(SET echooff=OFF)
@ECHO %echooff%
SET lqpp=%~1
(SET "lqpp"
1>NUL 2>NUL)||(SET "lqpp=1000000")
FOR /L %%a IN
(1,1,%lqpp%) do (
echo %%a
IF %%a EQU 3 GOTO
:break
)
:break
ECHO Saime minema!
PAUSE >NUL
EXIT /B 0
Kuni for-ni tegeldakse
programmis sellega, et kuidas forever2 parameetreid sättida.
Praeguseks hetkeks piisab teadmisest, et ECHO on lülitatud
OFF ja lqpp on 1000000 (miljon), kui forever2
käivitada ilma igasuguste parameetriteta.
Käivitage forever2.
Märkate, et
millegipärast on tekkinud umbes 10 sekundiline paus. ( või pikem /
lühem, sõltub pillist). Aga koodis on selge sõnaga öeldud, nagu
eelmiseski tsüklis, et hoolimata tsüklimuutujast lqpp
tehakse tsüklit 3 korda ja siis minnakse :break märgendi
peale.
Kuidas see on võimalik, iga tsükli peale tänapäevases arvutis 3 sekundit kulutada?
Kuidas see on võimalik, iga tsükli peale tänapäevases arvutis 3 sekundit kulutada?
See ei ole uni,
batmanid. See on .bat keel!
Et seda selgitada,
lisan ka programmi kirjelduse.
%1 parameetri vaikeväärtus on 1000000. %2 parameetri vaikeväärtus on OFF (echo seis).
%1 parameetri vaikeväärtus on 1000000. %2 parameetri vaikeväärtus on OFF (echo seis).
Lülitage nüüd echo
on ja pange %1 5-ks.
forever2 5 ON
annab järgmise
väljundi. Selle üle tasub mõtiskleda.
C:\bat>forever2 5
ON
C:\bat>SET lqpp=5
C:\bat>(SET
"lqpp" 1>NUL 2>NUL ) || (SET "lqpp=1000000"
)
C:\bat>FOR /L %a
IN (1 1 5) do (
echo %a
IF %a EQU 3 GOTO
:break
)
C:\bat>(
echo 1
IF 1 EQU 3 GOTO
:break
)
1
C:\bat>(
echo 2
IF 2 EQU 3 GOTO
:break
)
2
C:\bat>(
echo 3
IF 3 EQU 3 GOTO
:break
)
3
C:\bat>(
echo 4
IF 4 EQU 3 GOTO
:break
)
C:\bat>(
echo 5
IF 5 EQU 3 GOTO
:break
)
C:\bat>ECHO Saime
minema!
Saime minema
C:\bat>PAUSE
1>NUL
Niisiis ei tee programm
kuulmagi nõudmisest minna märgendi :break peale, kui %%a saab
võrdseks 3-ga, vaid ta lihtsalt ei täida küll käske, aga käib
tsükli päises ikkagi oma numbrit suurendamas ja kui echo on
lülitatud ON, siis väljastab täidetava käsu, kuigi mingi havi
käsul seda jälle ei täideta, vaid minnaks tsükli algusesse
tagasi.
Kasutajale
emuleeritakse GOTO :break käsku, aga ei täideta.
Järeldus:
FOR tsüklite sees ärge
kasutage GOTO käsku. Kasutage mingeid funktsioone ja käsku
EXIT /B 0,
aga mitte mingil juhul
GOTO-d.
Märkus: FOR /F puhul
ma küll sellist käitumist ei märganud, nagu FOR /L tsüklis, kuid
stackoverflow põgus
sirvimine näitab, et GOTO tekitab küllaga probleeme ka teiste FOR
võtmete puhul.
Enne FOR /F
üllatusteni jõudmist aga lühidalt programmi algusest.
@SET echooff=%~2
REM - %~2 loeb sisse %2
väärtuse nii, et kui selle ümber on jutumärgid, võetakse need
ära.
REM ka for
tsüklimuutujatega saab nii teha, lisaks veel igasuguseid trikke. vt.
FOR ? -st.
@SETLOCAL
enableExtensions enableDelayedExpansion
REM @ SETLOCAL ees
ütleb - seda käsku ei väljastata, isegi kui ECHO on ON.
SET "muutujanimi"
annab ERRORLEVEL 1, kui muutujaväärtus on tühi. || täidab
järgneva käsuploki käsu ainult siis, kui eelmine käsk andis vea,
s.t. ERRORLEVEL. See tähendab, et kui parameetrit %2 ei ole antud,
siis selle väärtuseks, ECHO väärtus siis, tuleb OFF.
&& muuseas
täidab järgneva käsuploki käsu siis, kui eelnev käsk oli edukas.
@ECHO %echooff%
REM siin lülitatakse
ECHO sisse või välja...
SET lqpp=%~1
REM FOR tsükli
ülemiseks piiriks on vaikimisi 1000000, et tekitada tuntav viivitus.
REM 1000000000 oleks
tõeline FOREVER!
FOR /F vigane ja
kasutu tulevärk faili sisu analüüsiks
Esimesel pilgul on FOR
/F äärmiselt aukartustäratav konstruktsioon.
Selle käsu grammatika
on selline:
FOR
/F
["valikud"] %%tsüklimuutuja IN
(failinimede_loetelu) DO käsk või käsuplokk
(failinimede_loetelu) DO käsk või käsuplokk
Käsk võtab failinimede_loetelust järjest faile, avab need ja iga
iteratsiooni käigus loeb failist järjekordse rea.
Faili lõppedes see suletakse, avatakse järjekordne fail ja nii
edasi ja edasi... Rida jagatakse valikute sees antud juhtnööride järgi juppideks
(tokens), millega DO käsk või käsuplokk saab teha operatsioone,
mida programmeerijal on pähe tulnud nende juppidega teha.
Esimene hoiatus - FOR /F ei tee absoluutselt midagi tühjade ridadega.
Neid ignoreeritakse, programmeerijal puudub võimalus
(esimesel pilgul) teada saada, kas rida on tühi või ei ole.
Teine hoiatus - VAIKIMISI ignoreerib FOR kõiki ridasid,
mis algavad ; -ga. Seda saab muuta parameetri eol sättimisega. Kahjuks seda
parameetrit ei saa ilma spetsiaalse süntaksilise nipitamiseta
muuta tühjaks, s.t. mingi "kommentaari"
sümbol peab olema vaikesüntaksis olemas.
vt. allpool ja veel
<9a>,<9b>
Valikud: delims=xxx – Sümbolite loetelu
eraldajatest juppide (tokens) vahel, mis
heidetakse rea analüüsil lihtsalt kõrvale.
Vaikimisi on nendeks sümboliteks tühikud ja
tab-d.
skip=n Mitu rida jätta analüüsist
välja faili alguses. Vaikimisi on skip väärtus 0. eol= See on täht, millega algavaid
ridu ignoreeritakse. Kui see täht on õnneks
mingi delims parameetriga antud täht, siis
seda ei juhtu. Nii saab alati, kui delims
sümbolid on olemas, eol panna võrdseks delims
mingi sümboliga ja kõik read, v.a. muidugi
tühi rida, lähevad käiku. Vaikeväärtus on semikoolon ; - üsna vastik
üllatus neile, kes ei ole viitsinud RTFM
soovitust järgida. tokens=x,y,...,z,* / või ka lihtsalt *. Ütleb, mis juppidega (tokens)
for tsüklis üldse tegeletakse. x,y,z on numbrid,
juppide lugemine algab 1-st. ,* lõpus tähendab,
et z järel tulev sõne reas (seda juba koos
eraldajatega) on terviklik jupp. z tagant
on eraldajad siiski eemaldatud. Vaikimisi võetakse ette vaid esimene jupp. Rida, mis sisaldab tere , ... talv, ... veel midagi annab tokens=1,* väärtuse puhul puhul esimeseks
jupiks tsüklile käitlemiseks tere ja teiseks
jupiks tuleb talv, kui delims=,." (punkt ja koma, " lõpetab
parameetrite andmise.) Kuidas need jupid muutujate vahel ära jagatakse, sellest allpool.
Praegu lihtsalt võtame teadmiseks, et tokens, delims parameetrite
abiga jagatakse rida juppideks ja teatud jupid antakse edasi tokens -s
määratud järjenumbritega do käsuplokile. tokens võib olla ka vahemik näiteks 1-6 - esimesed 6 juppi. usebackq on ebaõnnestunud süntaksi järelm.
Kuna failinimed võivad sisaldada tühikuid,
jutumärkidega eraldatud objekt IN sulgude sees
aga tähistab sinna kirjutatud sõnet (string)
vaikimisi, siis oli vaja sisse tuua erand. Nüüd kui usebackq on sisse lülitatud, siis
jutumärkide sees võib olla ka failinimi
(hurraa, lõpuks saab selliseid faile ka uurida,
kus failinime sees on tühikud). Nüüd
muutujate sisu / stringi analüüsi jaoks
on vaja see ümbritseda ühekordsete jutumärkidega,
mis varemalt jälle tähistas seda, et
ühekordsete jutumärkide seest võeti mingi
WINDOWS käsu väljund. Ja windows käsu väljund tuleb nüüd ümbritseda
tagurpidi jutumärkidega (backquotes, Esc all
enamikel klaveritel). PUHH. Väga õpetlik asi tõestamaks, milline
käkk lõpuks tekib halvasti välja mõeldud
programmikonstruktsioonist, kus ühe käsu /
konstruktsiooni alla tahetakse toppida tuhat asja. Juppide jagamine tsüklimuutujate vahel Ja ikka veel ei ole kannatamatule lugejale selge, mis saab juppidest,
kuidas nad muutujate vahel ära jagatakse. Selle panevad
paika tsüklimuutuja ja tokens poolt etteantud järjenumbrid. Oletame näiteks, et selleks muutujanimeks on %%a ja tokens=1,3,* Uuritavast reast võetakse nüüd arvesse 3 juppi - esimene , kolmas
ja kolmanda jupi järel tulevad jupid kõik koos (*). Esimene arvesseminev jupp läheb muutujasse %%a ,
teine jupp (3.) %%b-sse, kolmas (*) %%c – sse tähestiku järjekorras. Kui juppide arv on üle 31, tuleb hakata trikitama, ühes for
tsüklis ei saa rohkem juppe, kui 31 käsitleda. Aga kui delimiter on näiteks ',' (koma), siis ka mitu koma
teevad sama välja. Kuna csv failides kaks järjestikust koma tähistavad nende vahel
peituvat tühja välja, siis ei saa .bat FOR /F käsklus hakkama .csv
failidega ja sellist võtit ei ole ka, et kasutada eraldajana vaid ühte
delimiteri märki. Järelikult selline jupitamine võib sageli olla vigane ja sellest tuleks loobuda. Mingisugune väljapääs oleks FOR /F –i kasutada vaid faili ridadeks jagamisel, kuid ma ei ole veel leidnud meetodit, kuidas arvestada tsükli sisse tühje ridu.
FOR lihtsalt ignoreerib neid! Kui tühjade ridade mittearvestamine pole oluline, tuleb
FOR /F parameetrites kuidagi saada delims ja eol väärtused tühjaks.
Delims tühja väärtusega ei teki probleeme, eol-ga aga tekib –
vigase programmi tõttu ei saa kasutada jutumärke ja ilma jutumärkideta
tuleb eol= omistus igal juhul panna parameetrite sõne lõppu. Selleks peab erisümboleid peab veel paosümboliga ^ kaitsma. vt. lähemalt <9b> Ühesõnaga - FOR tsükkel, kus %%a saab enese väärtusteks uuritava faili
’andmed.txt’ read, jättes välja tühjad, on niisugune: FOR /F delims^=^ eol^= %%a in (andmed.txt) do echo %%a
Veendusime, et
tekstifailide süsteemse analüüsi vahendiks FOR /F tsükkel ei
kõlba.
For /F
kasutamine sõne sisu analüüsiks:
Kui IN järel
tulevas suluavaldises on üks nimetus ja see on jutumärkides, siis
see tähistab vaikimisi sõnet / stringi. Kui kaval võti usebackq
on sees, siis on tegemist failinimega ja vaid ühekordsete
jutumärkide vahele panemisega saab hakata uurima sõnet / muutuja
väärtust.
Jutumärkide vahele
kirjutatud %muutujanimi% võimaldab analüüsida muutuja sisu.
Näiteks:
set "hei=ai oi
ui"
FOR /F "tokens=1-3"
%a IN ("%hei%") do @echo %a/%b/%c
annab
käsurealt
ai/oi/ui
FOR /F
cmd käsu väljundi analüüsiks.
Kui ’FOR /F’ IN
suluavaldise nimetus on ühekordsetes jutumärkides või hoopis
tagurpidi jutumärkides (backquotes, Esc all, usebackq lüliti
sisselülituse korral), hakkab for tsükkel rida realt uurima selle
käsu väljundit.
See on küll kohmakas,
aga väga vajalik viis ühe funktsiooni / käsu väljundi uurimiseks
ilma vahepealset ajutist faili tekitamata.
Mõnikord on need arvutid, kus .bat programm võiks toimida, ära keelanud failide loomise .bat töökataloogis ja ometi peab .bat programm hakkama saama ilma ajutiste failideta.
Mõnikord on need arvutid, kus .bat programm võiks toimida, ära keelanud failide loomise .bat töökataloogis ja ometi peab .bat programm hakkama saama ilma ajutiste failideta.
Näide käsurealt:
for /F "tokens=1-5"
%a in ('dir ') do @echo %a %b %c %d %e
Ühe käsu väljund
võib oma väljundi toru/pipe sümboli kaudu suunata teise
käsu sisendisse.
Sulgavaldise sees tuleb
toru sümboli ette kirjutada pääsusümbol ^.
Näide
käsurealt:
for
/F "tokens=1-5" %a in ('dir ^| find /v /n "" ')
do @echo %
või
for /F "tokens=1-5"
%a in ('dir /b ^| find /v /c "" ') do @echo %
Find /v ""
tegelikult teeb failist /teise käsu
sisust koopia, aga seejärel find mõned võtmed on kasulikud:
/n
kirjutab ette rea numbri
/c
loeb lihtsalt read ära. Esimeses näites andsime järjenumbrid dir
väljundile ja teises näites lugesime
nii ära, mitu faili oli kataloogis.
PS!
Nii saab lugeda ära dir
võtme /s
abiga ka kõikide failide koguarvu koos jooksva kataloogi
alamkataloogidega ....
FOR
/R – rekursiivelt mööda puud alla
FOR
R üldkuju:
FOR
/R %%t ähtmuutuja IN (mallid) do
Näide:
for
/R % %G IN (*.dll *.exe) do @echo %G
loetleb
kõik dll ja exe failid käsurealt täidetuna.
Kõik
oleks tore, kui see FOR /R ei
tooks kaasa üllatusi
Käsu
“korraliku” täitmise eelduseks on, et
IN
avaldiste mallid peavad tingimata sisaldama erisümboleid, vähemalt
üks * või ?
See
ja paljud muud asjad ei ole dokumenteeritud “ametlikus” Windowsi
dokumentatsionis.
Näiteks *.jpg sobib, aga pilt.jpg ei sobi – see on konkreetne failinimi.
Veel hullem – programm annab sellel juhul hulganisti valepositiivseid vastuseid, s.t. käitub vigaselt.
Näiteks *.jpg sobib, aga pilt.jpg ei sobi – see on konkreetne failinimi.
Veel hullem – programm annab sellel juhul hulganisti valepositiivseid vastuseid, s.t. käitub vigaselt.
Illustreerin seda
näitega käsurealt ...
Olgu mul näiteks oma c:\bat kataloogis fail ruudud.cmd
Olgu mul näiteks oma c:\bat kataloogis fail ruudud.cmd
Kui
ma olen unustanud, kas mul on kataloogis c:\bat
selline fail, saab selle olemasolu kontrollida käsuga
FOR
%a IN (ruudud.cmd) DO @echo %a
Vastus on õige ja
positiivne, nagu võibki eeldata.
ruudud.cmd
Olgu mul nüüd tehtud
alamkataloog oma failidest nimega bak ja kõik c:\bat
failid mingi kuupäeva seisuga kopeeritud sinna, k.a. ruudud.cmd
Vaatame, kuhu ma olen
oma alampuus koos varufailidega ruudud.cmd faili veel pannud:
Kasutame /R
lülitit.
FOR /R %a IN
(ruudud.cmd) DO @echo %a
C:\bat\ruudud.cmd
C:\bat\bak\ruudud.cmd
Suurepärane!
Aga
äkki olen tegelenud .bat
keeles ka arvude kuupide arvutusega?
for
/R %a IN (kuubid.cmd) do @echo %a
Vastus:
C:\bat\kuubid.cmd
C:\bat\bak\kuubid.cmd
Selgub
siiski pärast mõningast järelemõtlemist ja otsimist, et
kuubid.cmd
faili pole kuskil pool.
FOR
/R võtmega tsüklis on sees väga
vastik viga – millegipärast eeldatakse IN sulgavaldises kõkide
mallide puhul kas *
või ?
märkide sisaldumist ja mittesisaldumise korral antakse tagasi
väärinfot.
Kui
mallid ei sisalda metamärke, siis loetletakse kõik kataloogid, mis
etteantud kataloogipuus on ja nendele katalooginimedele lisatakse
MILLEGIPÄRAST otsitud failinimed IN sulgavaldise seest.
Avatud
lähtekoodiga tarkvarade puhul oleks see skandaalne viga ammu
kõrvaldatud.
W ei
kavatse seda teha iialgi, hoolimata igapäevastest “kriitilistest”
uuendustest, mis väga sageli meie väärtuslikku aega raiskavad.
Märkus:
FOR
–l on veel lisaks /R
–le /D
võti. Räägitakse, et /R
ja /D –d
saab koos kasutada ja räägitakse, et sel juhul uuritakse
kataloogipuu katalooginimesid, mitte failinimesid....
Märkus:
W
.bat keelt
saab parandada. Seda on tehtud W –ga mitte seotud programmeerijate
poolt.
Tulemus
on saadaval nimega
TCC/LE
Windows CMD Replacement Shell <10>
X BAT ja sõned
Kunagi oli väga
populaarne lasteraamat pealkirjaga “Peep ja
sõnad”.
Peebul
oli raskusi suurte inimeste keelest arusaamisega, näiteks “Vesi
ahjus”
BAT-l
on oma sünnist saati olnud raskusi sõnedega
(välismaa keeles stringid).
Sõned
koos tekstifailidega on aga endiselt programmeerijate peamine
lähtematerjal. On programmeerimiskeeli, kus kõik, mis on, ongi
sõne: TCL (Ousterhoot).
Kui
sõnedega ei viitsita korralikult vaeva näha ja puuduvad
sõnetöötluse käsud, siis on programmeerimiskeel peaaegu kindlasti
kipakas.
Ka
küürakat üritatakse elu jooksul sirgeks saada, kuigi enamasti
tulemusteta ...
BAT
on samuti ühte kui teist õppinud. Uurime siis, kuidas seda ühte
kui teist sõnedaga teha.
A:
Ülesanne – teisendada Hallo World suur- või väiketähtedeks.
BAT
ei ole suvatsenud ise teha mitte ühtegi funktsiooni sõnede
teisendamiseks suur või väiketähtedeks, kuigi ise kasutab neid
tehteid oma sisemises tegevuses sageli.
Selle
tõestuseks sobib W käsurea käsk find:
C:\bat>find
"" ruudud.cmd
----------
RUUDUD.CMD
Viimane
rida peab tähendama, et find
ütleb, ma ei leidnud ruudud.cmd-st
seda sõnet. Kõrvalnähtusena näeme, et ruudud.cmd on teisenenud
SUURTÄHTEDEKS.
PS!
Find on kasulik käsk.
find
“” ei leia
kunagi mingist failist mitte midagi. Võtmed /v tähistavad eitust,
seega
find
/v “” tagastab iga rea. Find-l on
olemas võti /c – loeb lihtsalt ära tulemuse – mitu klappivat
rida leidis. Järelikult
find
/v/c “” loeb üle faili ridade arvu.
find
/v/n “” kleebib failile külge
rea numbrid.
See
asjaolu võimaldab find –i
isegi kasutada suurtähtedeks teisendusel – teeme find
käsu mitteolemasoleva failinimega, milleks on teisendatav sõne +
lisandid ehk, näiteks tühikud, et see fail kindlasti ei oleks
olemas ja õngitseme välja tagastatavast reast
file
not found ...
teisendatava
sõne.
(idee on reaalselt
kasutusel).
Näide võimalikust
kasutusest:
C:\bat>find ""
kuubid.cmd
File not found -
KUUBID.CMD
Nüüd oleks vaja
vastusereast kätte saada KUUBID.CMD
Selliseid trikke,
kasutades .bat sisemisi funktsioone, mis mingi teksti ise
suurtähtedeks teevad, on pakutud mitmeid.
Sellest hoolimata on
ainukeseks süsteemseks lahenduseks BAT enda mõne
sõnetöötlusfunktsiooni rakendamine.
Neid ei ole palju ja
ühe tekstijupi asenduseks teisega sõne seest sobib selline SET
käsk:
SET muutujanimi=%muutujanimi:mida asendada=millega asendada%
Näiteks:
set hei=hai
set "hei=%hei:a=i%"
echo %hei%
hii
See
asenduskäsk on asendatava sõne tõstu
(capitalization) suhtes tundetu.
set hei=hAi
set "hei=%hei:a=i%"
echo %hei%
hii
See
tähttäheline asendustegevus ongi aluseks upper.cmd
programmi funktsioonide toupper
ja tolower
toimimisele.
(Eesti
tähestiku ja utf-8-ga ma siin traktaadis igaks juhuks ei tegele,
seetõttu jäävad täpitähtedega
asjad nirudeks, minult abi ei saa)
Programm
upper.cmd
@ECHO
OFF
::
Programm sõne %1 teisendamiseks suur- ja väiketähtedeks, tulemused
väljastatakse ekraanile
SETLOCAL
EnableExtensions EnableDelayedExpansion
::
~ märk eemaldab %1 ümbert jutumärgid, kui %1 on nendega
ümbritsetud.
SET
"sqneU=%~1%"
SET
"sqneL=%~1%"
CALL
:UpCase sqneU
CALL
:LoCase sqneL
echo
Etteantud sõne oli: %1
echo
Suurtähtedes on sõne: %sqneU%
echo
Väiketähtedes on sõne: %sqneL%
pause
ENDLOCAL
GOTO:EOF
:LoCase
::
Funktsioon sõne väiketähtedeks teisendamiseks.
::
teisendatava muutuja nimi on parameeter.
SET
%1=!%1:A=a!
SET
%1=!%1:B=b!
SET
%1=!%1:C=c!
SET
%1=!%1:D=d!
SET
%1=!%1:E=e!
SET
%1=!%1:F=f!
SET
%1=!%1:G=g!
SET
%1=!%1:H=h!
SET
%1=!%1:I=i!
SET
%1=!%1:J=j!
SET
%1=!%1:K=k!
SET
%1=!%1:L=l!
SET
%1=!%1:M=m!
SET
%1=!%1:N=n!
SET
%1=!%1:O=o!
SET
%1=!%1:P=p!
SET
%1=!%1:Q=q!
SET
%1=!%1:R=r!
SET
%1=!%1:S=s!
SET
%1=!%1:T=t!
SET
%1=!%1:U=u!
SET
%1=!%1:V=v!
SET
%1=!%1:W=w!
SET
%1=!%1:X=x!
SET
%1=!%1:Y=y!
SET
%1=!%1:Z=z!
GOTO:EOF
:UpCase
::
Funktsioon sõne suurtähtedeks teisendamiseks.
::
teisendatava muutuja nimi on parameeter.
SET
%1=!%1:a=A!
SET
%1=!%1:b=B!
SET
%1=!%1:c=C!
SET
%1=!%1:d=D!
SET
%1=!%1:e=E!
SET
%1=!%1:f=F!
SET
%1=!%1:g=G!
SET
%1=!%1:h=H!
SET
%1=!%1:i=I!
SET
%1=!%1:j=J!
SET
%1=!%1:k=K!
SET
%1=!%1:l=L!
SET
%1=!%1:m=M!
SET
%1=!%1:n=N!
SET
%1=!%1:o=O!
SET
%1=!%1:p=P!
SET
%1=!%1:q=Q!
SET
%1=!%1:r=R!
SET
%1=!%1:s=S!
SET
%1=!%1:t=T!
SET
%1=!%1:u=U!
SET
%1=!%1:v=V!
SET
%1=!%1:w=W!
SET
%1=!%1:x=X!
SET
%1=!%1:y=Y!
SET
%1=!%1:z=Z!
GOTO:EOF
B:
Ülesanne: eraldada muutujast var kohas n k tähte.
Märkus:
Õnneks
on .bat
keeles võimalus kindlast positsioonist väja õngitseda mingi arv
tähti.
Üldiselt
mingeid muid võimalusi .bat
–s sõnetöötluseks eriti ei ole. Kuid koos võimalusega asendada
üks sõne teise sõne sees millegi muuga saab kõik sõnetöötlus
algoritmid ise põlve otsas valmis ehitada ja seda ongi sageli
Interneti avarustel tehtud.
Kui
aga ei veel ole, saab seda ise teha, ajades vastava algoritmi
kirjelduses näpuga järge.
Muutujast
alamsõne eraldamise süntaks:
%var:~ < Mitu t ähte muutuja algusest jätta välja> %
%var:~ < Mitmes t äht, alatakse 0-st >, < Mitu s ümbolit > %
ehk:
%var:~n,k%
Teisisõnu,
sõne tähed indekseeritakse alates indeksist 0 ning eraldatakse
välja
k
sümbolit alates positsioonist n.
%%
asemel saab (ja on sageli väga vaja) kasutada !!
märke.
Näiteid:
C:\bat>SET
"kevade=Kui Arno isaga koolimajja saabus"
C:\bat>set
arno=%kevade:~4,4%
C:\bat>set
arno
arno=Arno
Negatiivne
indeks tähistab lugemist sõne tagantpoolt ettepoole.
Ka
k-d saab negatiivselt tõlgendada.
Kõigepealt
eraldame sõnest välja alamsõne, alates positsioonist n (lugemist
alustatakse 0-st).
Saadud
sõnest aga eraldame välja kõik sümbolud KUNI positsioonini k.
C:\bat>echo
%kevade:~-1%
s
C:\bat>echo
%kevade:~-6,5%
saabu
C:\bat>echo
%kevade:~-6,-1%
saabu
C:\bat>echo
%kevade:~-10,-5%
jja
s
Kui
aga indeksid ise on .bat muutujad?
Sel
juhul päästavad hädast välja HÜÜUMÄRGID (ja muidugi
enabeDelayedExpansion)
C:\bat>set
neli=4
C:\bat>set
seitse=7
C:\bat>echo
!kevade:~%neli%,%seitse%!
Arno
is
Seda trikki kasutades
saab kirjutada funktsioone, mis mingit sõnet täht – tähelt
analüüsivad ja järelikult saab nii teoks teha kõik mõeldavad
sõneanalüüsi algoritmid.
XI
Miks me ikkagi armastame bat keelt, batmanid?
Lõpuks rauges ka minu
hoog.
Esialgu sai ta toitu
üllatusest ja ärritusest – kuidas tsüklist ei saa kuidagi välja,
miks muutuja ei muutu, miks ei ole võimalik ennast
programmeerimiskeeleks pidavas süsteemis normaalselt kommenteerida
...
Seejärel tekkis
sportlik hasart – kas TÕESTI ei ole MS-s .bat keeles ühtegi
kohta, kus ei esineks naeruväärsusi. Seni ei ole ma selliseid
leidnud – alati leiate mõne põneva kala.
Oma kulutatud aja
põhjenduseks oli vaja leida veenvaid valesid. Üheks selliseks
sobis programmeerimiskeelte võrdlev analüüs. Heakene küll, otsime
häid programeerimiskeeli või vähemalt rahuldavaid. Aga midagi
võiks olla ka sellist, mis oleks peaaegu igas suhtes halb.
.BAT on selleks päris
hea kandidaat.
Ka reaprogrammeerijad
leiavad ennast sageli mingi funktsiooni süntaksi kavandamisel
samasuguste valikute ees ja aeg ajalt oleks kasulik õppida ka
sellest, mida EI TASUKS TEHA.
Teine argument, vahest
ainukene, mis reaalselt õigustaks .bat keelele pühendatud
aega asiste tööinimeste puhul – teil ei ole muud võimalust.
Kunagi elasime NSVL-s.
Meil ei jäänud muud üle. Kui ei olnud mingit asja võimalik teha
mõistlikul moel, tuli leida mittemõistlik viis millegi tegemiseks.
W administraatorid
leiavad ennast sageli sellistest olukordadest. Teie töötuppa
astuvad sisse mitmesuguse isikud, kes tahavad teie võrku kasutada ja
teie hooldusteenust. Enamasti ei ole aega nende arvutitega liiga
palju tegelda. Seal võib kohata igast ajastust pärit pille. Ja
ainukene „keel“, mis kõigi W arvutite peal enam-vähem kindlasti
jookseb, on .bat keel.
Ja isegi .bat keeles on
võimalik automatiseerida tegevusi, mille peale muidu kuluks
võib-olla tunde....
Ja lõpuks, nagu
Tammsaarel Vargamäelgi juhtus – kui teha tööd ja näha palju
vaeva, hakkab seda iselaadset arvutikeele paroodiat omamoodi
armastama.
Mida selle teema kohta
on teised arvanud, seda vaadake ja tundke vähemalt kaasa:
<8>
XII
Viiteid.
Lingipuru:
Siit saate toitu
veendumusele, et te ei ole oma palatis üksi,
batmanid...
.BAT piibel, kõik teed
lõpuks viivad selle raamatu poole. Ei ole hankinud, seetõttu
soovitan.
Eestis ilmselt üheski
raamatukogus ega riiulis ei leidu, kui hangite, olete üks esimesi.
Ei välista, et lähen
ja tellin Krisost.
vt. veel 1-s viidatud
raamatuid, kui tunnete ennast W -le alla jäävat skriptimisel.
Millegipärast ma
kaldun arvama, et targem annabki järele...
Siin on kasulikku
informatsiooni ja linke ka teiste W skriptimiskeelte kohta.
Teemasid:
Asendamatu koht, mitte
ainult .bat keele kohta teadmiste hankimiseks.
Mina leidsin selle
olevat kõige korralikuma omasuguste seas .bat käskude
kirjeldamisel.
Väga hea DOS häkkerite
kogunemiskoht.
Palju
väärtuslikke praktilisi näiteid.
Siin
on sadu kirjutisi erinevate W, Linux-i ja Mac „trikkide” kohta
käsureal.
W,
Linuxi administraatorile kindel asi, mida peab teadma või kohe läbi
lugema ja siis teadma.
.BAT
FOR käskude harjutamiseks käsureal väga asjalik abimaterjal.
Siin
foorumis on tõesti toodud enamik vajaminevaid näpunäiteid .bat
programmeerimisel.
8.
http://stackoverflow.com/questions/2569833/what-are-the-reasons-to-use-dos-batch-programs-in-windows
Eksistentsiaalne
lähenemine teemale.
Väga
asjalik sissejuhatus .BAT -ga alustajatele, vahest üks parimaid.
Viited .BAT
spetsiaalprobleemidega seotud infole:
9. FOR /F tsükli
süntaks ning eol (kommentaari rea tunnusega seonduv):
10. TCC/LE cmd shell.
11. FOR /R:
metasümbolite vajadus IN mallides
12. Spetsiaalsetega
sümbolitega tegelemisest
b)
13. Uue rea sümboli
saamisest spetsiaalsesse muutujasse.
14. Kuidas
kommenteerida .BAT faile:
a)
Kommentaaride süntaks.
Jätan endale vabaduse
seda lingikogu võimalusel täiendada ja edasi kommenteerida.
Muud
viited:
15.
K & R C keele
piibel:
16. Dijkstra artikkel,
kus ta määratleb COBOLI õpetamist kui kriminaalset tegu.
Dijkstra, COBOL
17. Dijkstra veel
kuulsam artikkel, millest enamasti teatakse vaid pealkirja:
Goto considered harmful
18. Wiki ülevaade
võrdlusoperaatoritest, näete, et BAT on täiesti eriline siin
19.
Vähima üllatuse printsiibist Ruby loojalt Yukihiro Matsumotolt:
0 Comments:
Postita kommentaar
<< Home