PowerShelli koorimas I
Blogi omapära ja häda on tema ajakajalisus. See, mida
mõtlesid eile ja ütlesid eile,
jääb kivisse raiutuna internetti aastakümneteks.
Eile ma arvasin PowerShelli (PS) kohta üsna halvasti, põhinedes selle keele v1. pealiskaudsel kiirtutvusel aastaid tagasi. (vist 2008).
Eile ma arvasin PowerShelli (PS) kohta üsna halvasti, põhinedes selle keele v1. pealiskaudsel kiirtutvusel aastaid tagasi. (vist 2008).
See oli aeg, kui Windows XP-sid oli väga palju. PowerShell
nende kastide jaoks automaatselt ei toiminud, PS rakendamine organisatsioonis
oleks tähendanud lisapingutusi. PS oli siis veel toores, Alates v2. on PS
rakenduskõlbulik.
Serveritega sai ka vanaviisi õiendada - GUI - graafilise
kasutajaliidese - toel ja vajadusel kaugelt RDT -ga (Remote Desktop) asju
sättides...
Ühesõnaga, mugavustsoonis sai edasi elada. Pealekauba MS
toetas ja toetab jätkuvalt GUI põhist administreerivat mõtteviisi.
Ka MS siseselt tundub jätkuvalt eksisteerivat usulõhe, sest PS looja Jeffrey Snoveri manifest
Ka MS siseselt tundub jätkuvalt eksisteerivat usulõhe, sest PS looja Jeffrey Snoveri manifest
(vt. Monad Manifesto koos järelmõtetetega 2011) eksisteerib juba aastast 2002, PS v1 sai valmis 2006, PS v2 2009 ja alles viimasel ajal on hakatud rääkima
(konkurendi Linux mõjul?) ühest peamisest paradigma nihkest - DSC-st (Desired State
Configuration-st, Linux-ite Puppeti mõjul). Ühesõnaga, administraator paneb
konfifailides paika, millisena ta tahab oma lambaid näha ja lambad ise sätivad
ennast vastavaks administraatori nõuetega.
Elu ise teeb MS mõtteviisis aga korrektiive, sest ettevõtted
tahavad toime saada vähema arvu patsiga poistega, samal ajal, kui arvutite ja
serverite hulk kasvab ...
Nii on MS enda sees läinud käibele termin windowsi
"defenestreerimine"...
Aga näiteks ka minu vana
tööandja Alma sees lastakse vanaviisi edasi ja need inimesed, kes oleksid olnud
võimelised neid asju ellu viima ... koondati ära. Pärast vastavate tegelaste
istutamist juhtivatele kohtadele äkitselt "dünaamiliseks" muutunud
kollektiiv on seejärel saanud maha veel mitme pereheitmisega.
Tõsi, selle dünaamilisuse taha peidab ennast tõsiasi, et kogu dünaamika vaid lõpututes pereheitmistes seisnebki.
Tõsi, selle dünaamilisuse taha peidab ennast tõsiasi, et kogu dünaamika vaid lõpututes pereheitmistes seisnebki.
Aga jumal sellega. Riigi
(eriti meie riigi) asutuste puhul ei ole hea idee liialt süveneda nende
hingellu või tahta mingeid muutusi. Kui midagi toimib, keeratakse see xxxxx, ei
ole mingit garantiid organisatsiooni maabuva loodusõnnetuse eest. Hästi
toimimine / töötamine ei ole mingi argument. ...
Praegu vaatlen ma PowerShelli arendaja vaatepunktist ja
jälle tuleks oma hoiakuid revideerida -
PowerShell võiks olla igale C# arendajale töövahend.
Mõlemad põhinevad .NET -l, mõlemate ellukutsumise põhjuseks
on see raamistik, seetõttu lähemal vaatlusel on üks keel teise
"dialekt".
Kõik need tõsiasjad
oleksid jäänud mul aga täiesti tähelepanuta, kui poleks olnud vajadust läbi
sirvida skriptivate keelte loomaaed ülevaate saamiseks ning .bat keel oli
ainukene, mida ma tundsin windows -st (VBS ja JavaScriptil põhinev JS on
tegelikult paremad variandid kasutamiseks).
Jõudsin lõplikule järeldusele (vt. Sekeldaja "Pakkfailide
feilimisest" I & II), et .bat keel on programmeerimiskeelte
seas vaieldamatult üks kipakamaid ja meeleheide (mingi skriptimisvahend võiks
MS-l ju siiski ka toimida) sundis veel kord üle vaatama PS-i.
Ja veelkordne üllatus (suurima üllatuse printsiip MS
maailmas!):
PowerShell on
täiesti kõlbulik programmeerimiskeel!
Äkki on PS operatsioonisüsteemide kesti (shells)
programmeerivate keelte seas ehk isegi üks parimatest?
Viimane asjaolu on seotud PowerShelli suhtelise noorusega ja õnneks sellega, et selle keele loojad on midagi ikkagi õppinud eelnevate keelte vigadest ...eriti ehk muidugi DOS.
Viimane asjaolu on seotud PowerShelli suhtelise noorusega ja õnneks sellega, et selle keele loojad on midagi ikkagi õppinud eelnevate keelte vigadest ...eriti ehk muidugi DOS.
Aga aitab filosoofilisest grafomaaniast:
Küülikuagust alla
1. Monadoloogia ja võtmetekstid:
Leibnizil on üks tähtis filosoofiline teos - vt.
Omab väga vähe pistmist Powershelliga, v.a. võtmesõna monaad.
Otsing Monad Powershell viib aga olulise võtmetekstini:
Otsing Monad Powershell viib aga olulise võtmetekstini:
Järgnev on aga PS olulisim võtmetekst:
2. Võtmeisikud:
2.1 . Jeffrey Snover
http://jsnover.com
2.2 BRUCE PAYETTE
2.3 MUFTI
Raamatu "Power Shell in action" kaanepilt kujutab
muftit - vaimulikku, kelle ütlused ühe või teise asja kohta on siduvad
usujüngritele.
Võtke seda pilti tõsiselt ja ärge raisake esialgu liiga
palju aega muude tekstide peale, kui
“PowerShell
in action”
3. Ajalugu
/ üks kulunud tsitaat ütleb, et kõik, kes
koolis ei õpi ajalugu, on määratud kursust kordama ... /
PowerShell (edaspidi PS)
ei ole olnud oodatud tegelane MS nukuteatris. Pigem nagu
kõrvaltegelane, noorim vend vene muinasjuttudest.
Aga nagu vene muinasjutuski saab ta vist päranduseks ...
terve MS impeeriumi, sest uued serverid enam muid vahendeid peale PS
administreerimisel ei tunnista (nano).
2002 augustis, pärast umbes aastast tegevust Windowsi kesta
arendamisel, ilmus "Monad Manifesto".
Seejärel järgnes arendusprojekt, kus võtmeisikud asusid USA-s (Seattle), programmeerijad töötasid Indias. Pärast 18 kuu pikust ponnistamist alustati projektiga sisuliselt uuesti.
Probleemiks oli seisulik suhtumine Indias - Snover vajas enese kõrvale inimesi, kes ütelnuks, et nemad teavad paremini, kuidas mõnda asja teha, mitte Yes, Sir tüüpi käsutäitjaid.
Seejärel järgnes arendusprojekt, kus võtmeisikud asusid USA-s (Seattle), programmeerijad töötasid Indias. Pärast 18 kuu pikust ponnistamist alustati projektiga sisuliselt uuesti.
Probleemiks oli seisulik suhtumine Indias - Snover vajas enese kõrvale inimesi, kes ütelnuks, et nemad teavad paremini, kuidas mõnda asja teha, mitte Yes, Sir tüüpi käsutäitjaid.
PS loomist segas ka suurel määral MS Longhorn projekti
põrumine. Ja nii edasi ...
Kuid nov. 2006 ilmus PS v1
aug. 2009 PS v2.
7 aastat manifestist kuni esimeste viljadeni on
programeerimise maailmas küllaltki pikk aeg.
Snoveri rolliks oli öelda välja ebameeldiv tõde, et mõte sellest, et GUI võiks täielikult asendada käsurea interpretaatorit oli viga.
Snoveri rolliks oli öelda välja ebameeldiv tõde, et mõte sellest, et GUI võiks täielikult asendada käsurea interpretaatorit oli viga.
Lisaksin, et üks ärilisemalt õnnestunumaid vigu üldse, kui
lugeda MS ja Apple edulugusid.
Ja nüüd äkki - ei kõlba?!
4. Miks PS? Miks mitte GUI?
Kuigi kuulun ametilt nende inimeste hulka, kes
peaksid hirmsasti armastama käsurida, ei ole see siiski nii. Must/helesinine
ekraan käsurea promptiga ei tekita ei Linux-is ega DOS-s / nüüd siis PS-s
erilist vaimustust, kui just ei ole vaja.
Kunagi ammu Füüsika Instituudis läks elu DOS-s tunduvalt
lihtsamaks sellise huvitava programmi, nagu Norton Commander tulekuga. Tänaseni
kasutan - kasvõi Linuxis nime all mc.
Ka Windowsi või mac-iga õiendamine on GUI-d kasutades ÜHE
arvuti korral tunduvalt lihtsam, kuigi siin on ka piirid - väga keeruliste
programmide puhul võib mingi käsurea võimalus olla tunduvalt lihtsam, kui ei
tea kust kohast üles otsida mingi menüürida ja kusagile kastikesse sisse
klõpsida linnukene.
Kui aga arvuteid on näiteks terve arvutiklassi jagu?
Hiirega klõpsimist on väga raske automatiseerida. PS võimaldab endiselt kasutada graafilisi kasutajaliideseid, aga iga liigutus selles liideses kajastub vastava käsuna PS-s ja seda tegevust saab automatiseerida.
Hiirega klõpsimist on väga raske automatiseerida. PS võimaldab endiselt kasutada graafilisi kasutajaliideseid, aga iga liigutus selles liideses kajastub vastava käsuna PS-s ja seda tegevust saab automatiseerida.
Arvutiadministraatori kõige suuremad mured ei ole aga
hiireklõpsu / käsurea võimalik kokkuhoid.
Mõnikord võib mingi tegevus minna valesti. Sel juhul aga tekib küsimus sellest, MIS võis minna valesti ja sellest peaks jääma jälg.
Mõnikord võib mingi tegevus minna valesti. Sel juhul aga tekib küsimus sellest, MIS võis minna valesti ja sellest peaks jääma jälg.
Käsurea tegevused on isedokumenteerivad ja tulemused saab
salvestada.
Hiireklõpsu korral ekraanile ilmuv veateade on aga järgmine
hetk haihtunud.
Mõned vead, tõsi, jõuavad Windowsi "Event logi". Sealt nende väljaotsimine on üsna tüütu.
Mõned vead, tõsi, jõuavad Windowsi "Event logi". Sealt nende väljaotsimine on üsna tüütu.
Varem või hiljem jõuab iga ettevõte vajaduseni oma
arvutialaseid nõudeid süstematiseerida ja dokumenteerida.
Hiireklõpsupõhises arvutimajanduses on see keerukas, nõudes
sisuliselt topelttööd - teed kusagil klõpsu ja märgid kirja, kus see klõps
tehti ja mis asjaoludel.
Korralike skriptide kasutamisel on olukord vähemalt ideaalis
hallatav.
...
5. Aga miks PowerShell ?
Algselt tegeles ka Windowsi uut käsukesta arendav meeskond
põhiliselt Unix kesta ümbertõstmisega Windows keskkonda. Tulemus ei olnud
rahuldav,
Unixi kestad ei sobinud Windows API-dega ümberkäimiseks.
Ühes Snoveri presentatsiooni väidab viimane, et 4000000 $ kulus ära ideele Windows keskkonnas käima saada Unixi kest (ksh oli eeskujuks).
Ühes Snoveri presentatsiooni väidab viimane, et 4000000 $ kulus ära ideele Windows keskkonnas käima saada Unixi kest (ksh oli eeskujuks).
Seejärel kulus 60000 $ ideele arendada välja käsud WMI-ga
ümberkäimiseks. Ja siis, ühel jõulupuhkuse ajal kirjutas Snover PowerShelli
prototüübi.
Seejärel Monaadi manifesti. Palju edasi PS arendusele on
kulunud, jääb saladuseks, aga sellest hetkest hakkasid asjad soovitavas suunas
liikuma...
Ja nüüd, 2015 oleme siis niikaugel, et Windows arvutile saab
ette kirjutada, mis konfiguratsiooni peab see saavutama...
VBS ja JScript aga olid süsteemiadministraatori jaoks samuti
liiga kohmakad, kuigi olid (ja on tänini) kasutusel.
Aga ikkagi, miks Unix sh ei sobinud?
Aga ikkagi, miks Unix sh ei sobinud?
Näiteks:
A:
oskavad UNIX programmid edastada järgmisele konveierilülile
vaid struktueerimata teksti- või baidivoogu.
Kes ei tea - konveier (pipe) võimaldab ühe programmi
väljundit suunata teise programmi sisendiks. Konveieri leiutamine ise oli
kindlasti suurepärane idee ja ajaproovile igati vastu pidanud.
Ainult et selle realiseerimine Unixi kestas ei ole olnud
kõige õnnestunum.
Windows enda cmd-kestast ei maksa siin rääkidagi.
konveieri kahe programmi vahelises ühenduses kasutatakse
informatsiooni edastamiseks struktueerimata teksti, mida iga käsu sisendis
tuleb uuesti läbi sõeluda (parse).
Snoveril on selle kohta termin "prayer based parsing", "palveta ja sõelu".
Snoveril on selle kohta termin "prayer based parsing", "palveta ja sõelu".
Parem oleks ehk süüa, palvetada ja armastada tühja tähja
sõelumise asemel?
Et Unixis nii palju kasutatakse konveierit, on osalt
tingitud sellest, et Unixi töövahendid ei tee alati seda, mis nõutud.
Ühes töövahendis on peaaegu alati koos 3 tegevust -
objektide kokkukorjamine, objektide töötlemine ning seejärel tulemuste väljastamine
tekstina.
Kuid midagi ei toimi nii, nagu tahetakse, tuleb kasutada
konveierit ja pooleliolev töö edastada järgmisele lülile, mis sellest tekstist
võiks jälle üritada kätte saada infot objektide kohta.
Alati see ei õnnestu, administraator peab täpselt teadma ja
ette andma näiteks veeru numbri, kus peidab ennast käsu ls puhul faili
suurus ...
Näide - siin prindime välja faili nime ja
suuruse. Maagilised numbrid on 9 ja 5.
ls -l | awk '{print $9 " " $5 }'
PS asendas selle parandamiseks tekstilise sisendi/väljundi
objektidega..
Programmi muutujad on tegelikult .NET / WMI ... objektid, mis on PS enda
objektideks ümber lõigatud / adapteeritud objektide kogumid.
Alles konveieri lõppfaasis vormindatakse tulemid.
B: UNIX (aga ka DOS) kestade töövahendite nimetamises-käitlemises puudub
süsteem.
Põgus tutvus Unixiga näitab, et kesta kasutaja peab meeles
pidama rohkesti mnemoonilisi kahe-kolmetähelisi lühendeid (sed, awk, ls, rm.
cp, mv...), mis on sellised peamiselt ajaloolistel põhjustel....
Vist ei mõtle väga välja loogikat lühendi grep
desifreerimiseks?
PS asendas selle segadiku pisut parema tegusõna-nimisõna
süsteemis käsustikuga.
Käsklusi on endiselt palju, aga selles on nüüd mingi
süsteemi alged.
Kui objekte on vaja kokku koguda, siis algab käsk tegusõnaga get:
Kui objekte on vaja kokku koguda, siis algab käsk tegusõnaga get:
Get-Eventlog näiteks ...
PS skriptide tegemisel tuleks
lähtuda kahest stiilist. Lihtsates testskriptides või PS käsureal toimetades,
mis ei ole ette nähtud pikaajaliseks korduvaks kasutuseks, neis kasutage
aliaseid (Unix stiil, mida lühem, seda uhkem).
Kui aga skriptist tõotab tulla
midagi, mida saab ka edaspidi kasutada, kirjutage oma tekst üles pikemas ja
loetavamas kirjaviisis, loopides igal juhul välja iseenda poolt defineeritud
aliased j.m.s...
mis ei pruugi olla arusaadavad
neile, kes peavad neid skripte käitama / lugema. Siis sobib suurepäraselt
tegusõna-nimisõna süsteem.
Isegi omadefineeritud
skriptide -funktsioonide jaoks võiks üritada kasutada sellist
nimetamissüsteemi.
C: Käskude (cmdlet PS-s) parameetrite käitlemine ei ole
Unixis ega DOS-s olnud ühtne.
Eriti hull anarhia valitseb bat keele käskude parameetrite käitlemisel, kus pole isegi kunagi
selge, kus algab üks parameeter ja lõpeb teine, või koguni kus lõpeb üks käsk
ja algab teine...
...
D ---Z ja nii edasi ...
PS parandas neid varasemate OS kestade skriptimiskeelte
puudusi märkimisväärselt. Objektorienteeritus, kus käskude sisendid ja
väljundid on objektid või objektide kogumid on nendest muutustest kõige
olulisem.
6. PS alustused
Minul (hetkel) käsutuses olev
üks uunikumarvuti sisaldas XP, seetõttu ma siin ei juhata sisse ja pole väga uurinud uusimaid vidinaid ja vilesid.
Alustuseks ehk ei olegi see vajalik ja kui PS skripte on vaja
käivitada-kasutada väga mitmekesises arvutipargis, võib harjumus kasutada PS
moodsaimat versiooni lausa segada. Miinimum PS õppimisel on siiski PS v2, täpselt see, mida eeldab evangeelne
"Windows Power Shell in action".
6A. PS versioon
Tippige W7 vasakul allnurgas oleval käsureale real sisse powershell
/ või käivitage mingil muul viisil PS. XP puhul on vaja teha lisaprotseduure, ajapuudusel
jätan detailid välja, W 8.0/8.1 ja 10 ning igasuguste serverite variantide
puhul käivitusvariandid erinevad...
Tähetõstuprobleemid W-s puuduvad, aga süsteemsuse mõttes
formaadin edaspidi oma näited viisakamaks, et skriptimise puhul asjad kenamad
välja näeksid. Tegelikult ei ole vahet, kuidas tippida, ka PowerShell, POWERshell
viivad sihile.
$psversiontable peab ütlema numbri, mis peab
olema >=2.0
perfektsionistid tippigu
$psversiontable.psversion
siis saab kätte ainult versioonihalduse numbrid
(Major.Minor.Build.Revision) ja pääsete ülejäänust.
XP-l peab PS
käimahakkamiseks (kindlasti olgu v2) veidi vaeva nägema.
Märkusena
$ tähistab muutujanime algust, mis on kas objekt või
objektikogum (collection). Muutujanime tippimine toob ekraanile selle
sisust ühte teist, mida PS loojad peavad oluliseks, kuid vajadusel saab muutuja
sisust kogu informatsiooni kätte.
6B. Hello, World! lause käsurealt:
Õnnetuseks ei ole Hello world tegemiseks peaaegu üldse vaja
midagi õppida. Tuleb käsureale lüüa
"Hello, World!"
Saate Hello, World! ilma jutumärkideta (erinevalt DOS-st).
Teadjamad näevad siin, et lõpuks ometi on MS-s
aru saadud, et kuidagi tuleb sõnesid eraldada. Nagu Unix-is, on siin 2
võimalust - kahekordsed ja ühekordsed jutumärgid.
Nagu Unix-is asendatakse kahekordsete jutumärkide vahel
oleva sõne sees muutujat tähistavad sõned muutuja sisuga, s.t. sõnesid
interpoleeritakse. Lisaks muutujate asendamisele toimub veel erimärkide
asendamine.
Ärge aga kihutage siit kiirelt üle, sest teid ootab
ees üllatusmuna MS-lt. Tõtt öelda põhjendatult.
Paosümboliks on PS-is mitte langujoon, vaid backtick,
kaldkoma.
Kaldkoma on minu leiutatud
termin. Ülakoma juba on, miks mitte igasugustele komadele seltsiks lisada
kaldkoma.
Kaldkoma ehk backtick-i
leiab üles inglise klaviatuuri puhul Esc sümboli all, Eesti
klaviatuuripaigutuse korral backspace kõrvalt, shift klahvi kasutades.
Unix-is tähistab kaldkomade vahele asetatud sõne käsku, mis tuleb täita ja siis samasse kohta tagasi kirjutada.
Unix-is tähistab kaldkomade vahele asetatud sõne käsku, mis tuleb täita ja siis samasse kohta tagasi kirjutada.
Allpool ad nauseam näiteid hallotamisest:
PS C:\bat\power>
'hello world!'
hello world!
PS C:\bat\power>
"Hello, World!"
Hello, World!
PS C:\bat\power>
$Hello = "Hallo"
PS C:\bat\power>
$World = "Maailm"
PS C:\bat\power>
"$Hello, $World!"
Hallo, Maailm!
PS C:\bat\power>
'$Hello, $World!'
$Hello, $World!
Kaldkoma aga päästab ka dollarimärgi eritähendusest.
PS C:\bat\power>
"`$Hello, `$World!"
$Hello, $World!
Topeltjutumärkide vahel saadakse aru reavahetusest,
tabulaatorist jpm,
Ühekordsete jutumärkide vahel neid asju ei interpoleerita.
PS C:\bat\power>
"Hello,`nWorld"
Hello,
World
PS C:\bat\power>
'Hello,`nWorld'
Hello,`nWorld
Mõnikord tasuks sõnede sees täita mingi käsk ja tulemus
istutada selle sõne sisse.
Proovime.
Kõigepealt õpiks ära mõne kasuliku käsu.
Enamike õppetekstide arvates õppur ei oma aimu hetke
kuupäevast. Nii arvan ka mina.
Get-Date tagastab
kuupäeva-kellaaega sisaldava objekti.
PS C:\bat\power>
Get-Date
13. detsember 2015. a.
18:37:09
Seejärel saab sellest objektist kätte aastaarvu, pannes
esimese operatsiooni sulgudesse ja seejärel saadud tulemusobjektist leides
omaduse .year
PS C:\bat\power>
(Get-Date).year
2015
Sõne sisse istutame
selle tulemuse $(... ) operatsiooni
abiga.
PS C:\bat\power>
"Hello, World, anno $((Get-Date).year)"
Hello, World, anno
2015
Miks kaldkoma langujoone asemel paosümboliks sai on üsna
mõistetav, sest MS-s on sama sümbol ka katalooginimede eraldajaks ja selle
kasutamine paosümbolina oleks tekitanud suurt segadust.
Seevastu võite kasutada kataloogides navigeerimisel nii
kaldkriipsu kui langujoont, ‘/’ või ‘\’
sümbolit, vahet ei ole.
6C. Hello, World! programm
Tõsisema PS huvi korral installeerige arvutisse Notepad++ (sobib
väga hästi paljude teiste programmeerimiskeelte jaoks), seejärel aga hakake
uurima PS ISE võimalusi, praegu võib piirduda notepad-ga, nii et
notepad helloworld.ps1
koos sinna kirjutatud programmitekstiga
"Hello,
World!"
on täiesti piisav hakatuseks.
Kui nüüd PS käsurealt tippida helloworld, võiksite maailmatervitust näha.
Aga võta näpust.
PS aga soovitab selle asemele .\helloworld
–i.
Ka Unix-is on nii, ei maksa nördida ja PS on selle Unix-ilt
üle võtnud.
Vaid $env:PATH –s sisalduvates kataloogides olevaid
programme saab PS-s kasutada ilma rajata käitatava programmi juurde. Ülejäänud
programme tõmmatakse käima kas täisnime kasutades (pikk tee C:/..) või siis
lühikest, relatiivset teed kasutades, jooksva kataloogi puhul on kataloogi
tähiseks ’.’
Tööarvutites,kus ei ole vaja PS skripte kirjutada, vaid
ainult täita, nii peakski jääma. Arvutis, kus oleks ehk vaja kirjutada rohkesti
PS skripte. tuleks lisada PATH keskkonnamuutujale ’.’, seda PATH lõppu, mitte algusesse. Siis ei hakata näiteks dir
käsklust kohe otsma sellest kataloogist, kus asutakse, vaid PATH kataloogidest
ja kurikaeltel on vaja rohkem vaeva näha, et teie arvuteid kahjustada...
Alustuseks, sellega harjumise
(ja poliitilise korrektsuse) mõttes, jätkame endist viisi. Kui satute Linux
maailma, võib sellest harjumusest olla kasu. Ja jumala eest, ärge rääkige seal
kellelegi, et olete ka seal oma PATH muutuja ära sättinud nii, et oleks nagu
Windows-s!
MS enda puhul hm on selline turvalisus võrreldav olukorraga
I korrusel elades, kus uks on lukustatud, aken aga on pärani lahti. Sest .bat
käsuaknas ei nõua keegi selliste formaalsuste täitmist.
Edaspidi näete veel ühte sellist tüütust – ps1
laiendiga programmid ei hakka automaatselt tööle (ja .cmd/.bat laiendiga
hakkavad, nagu need oleksid mingid ohutuse etalonid).
Nii et meie praeguses kataloogis olevat helloworldi
programmi võiks käivitada käsk
./helloworld (või .\helloworld, kui olete MS
langujoonega harjunud. IMHO on jagamismärgi kasutamine mugavam).
Uus üllatusmuna
- PS1 programm vaikimisi käima ei
lähe.
Järjekordne tüütus ps1 kasutamise teel: ps1 vaikimisi
poliitika keelab ps1 skriptide täitmise...
PS C:\bat\power>
./helloworld
File
C:\bat\power\helloworld.ps1 cannot be loaded because the execution of scripts
is disabled on this system. Please s
ee "get-help
about_signing" for more details.
At line:1 char:13
+ ./helloworld
<<<<
+ CategoryInfo : NotSpecified: (:) [],
PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
PS1-ga tutvumise algfaasis ei maksa lasta ennast heidutada.
MS lihtsalt siin tahab näidata oma vägevust – vaikimisi ps1 käivitamise rezhiim
on selline, et ps1 skripte üleüldse käivitada ei saa.
( restricted).
Samal ajal igasuguste .reg, .inf failide, .cmd skriptide ja .bat
skriptide käivitamine suvalistel masinatel on täiesti OK ja süsadmin peaks
kõvasti vaeva nägema, et nii ei oleks. Tavaliselt pole tal selleks mahti.
Selle saladusliku executionpolicy
saab kätte käsuga Get-Executionpolicy-ga:
PS C:\bat\power>
get-executionpolicy
Restricted
Muutke see admin õigustes olles ära, abi saab
help
set-executionpolicy –ga võimalike väärtuste jaoks.
PS C:\bat\power>
set-executionpolicy remotesigned
Execution Policy
Change
The execution policy
helps protect you from scripts that you do not trust. Changing the execution
policy might expose
you to the security
risks described in the about_Execution_Policies help topic. Do you want to
change the execution
policy?
[Y] Yes [N] No
[S] Suspend [?] Help (default is
"Y"): y
Remotesigned tähendab, et allalaaditud skripte niisama käima
ei saa. Sihukene formaalne luud uksel ees...
Puhh.
Nüüd on suur töö tehtud ja
./helloworld läheb käima.
PS C:\bat\power>
./helloworld
Hello, World!
Teinekord, kui käsu sisu selge, kasutage võtit –force, et tüütust dialoogispämmist pääseda.
PS C:\bat\power>
set-executionpolicy -force restricted
PS C:\bat\power>
set-executionpolicy -force remotesigned
PS C:\bat\power>
6D: Kuidas vanaviisi
jätkata: Get-Alias
Õnneks ei pea PS uurimisel kõike uuesti õppima.
Kui on meeles DOS või bash mõned käsud, võib
neid kohe proovima hakata.
Enamasti on need olemas (copy, mv, cp, cd, pwd, dir
...). Seda saab kontrollida aga
Get-Alias / või lühemalt Alias käsuga.
Get-Alias / või lühemalt Alias käsuga.
Kõigepealt kasutage help käsku (mis tegelikult on
lühend või alias Get-Help käsule).
Seda on vaja kasvõi selleks, et teada saada käsu õige nimi
ning seejärel selleks,
et mõista PS / bash / DOS käsitluste erinevusi.
Näiteks tahate teada, mis käsk on dir analoog:
PS C:\bat\power> help dir
NAME
Get-ChildItem
SYNOPSIS
Gets the items
and child items in one or more specified locations.
....
Help-i edasilugemisel selgub, et dir käsku õige
nimega Get-ChildItem
saab rakendada mitte ainult failisüsteemis olevate failide
sirvimiseks, vaid igasuguste
pakkujate / providers puhul.
Võib tekkida küsimus, et mis asi on provider? Ärge
jookske kohe internetti guugeldama, kuigi ka nii võib.
Nagu Linuxis, on ka PS-s korralikud abitekstid enamasti olemas.
Nagu Linuxis, on ka PS-s korralikud abitekstid enamasti olemas.
Nagu Linux-is, on ka PS
abitekstid kohati krüptilised, kuid
umbes 3-ndal lugemisel juba mõistetavad. Nagu Linuxis ärge eeldage, et saate
abitekstidest 1-l katsel jagu. Erinevalt Linux-ist saate abitekstidest mõnikord
juba 3-ndal katsel jagu.
Siin aitab kõigepealt
PS C:\bat\power> help about
Name Category Synopsis
---- -------- --------
about_aliases HelpFile Describes how to use alternate names for
cmdlets and commands in Windows
about_Arithmetic_Operators HelpFile Describes the operators that perform
arithmetic in Windows PowerShell.
about_arrays HelpFile
Describes a compact data structure for storing data elements.
..........
................................
sealt leiate ka teema
provider-ite kohta:
PS C:\bat\power> help about_providers
TOPIC
about_Providers
........
..............
BUILT-IN PROVIDERS
Windows
PowerShell includes a set of built-in providers that you can use
to access the
different types of data stores.
Provider Drive Data store
-------- ----- ----------
Alias Alias:
Windows PowerShell aliases
Certificate Cert:
x509 certificates for digital signatures
Environment Env: Windows environment variables
FileSystem * File system drives, directories,
and files
Function Function: Windows PowerShell functions
Registry HKLM:, HKCU Windows registry
Variable Variable: Windows PowerShell variables
WS-Management
WSMan WS-Management configuration
information
* The FileSystem
drives vary on each system.
Näiteks Env: draiv sisaldab tegelikult windows
keskkonnamuutujaid, mis peaksid olema tuttavad juba DOS-st.
PS C:\bat\power>
dir env:
Name Value
---- -----
ALLUSERSPROFILE C:\ProgramData
..........................................................................................
.............................<spam spam spam> ........................
Variable: draiv sisaldab muutujaid.
PS-s on muidugi palju sisseehitatud muutujaid.
Tekitame muutuja $hello ja vaatame kas ta on Variable:
draivil olemas:
PS C:\bat\power> $hello="hallo"
PS C:\bat\power> dir Variable:hello
Name Value
---- -----
hello hallo
6E Ja nüüd: VETTE!
Proovin nüüd lõpuks talitada oma sõnade järgi. Ükskõik mis
keelt saab rääkima õppida rääkides, programmeerimiskeelt õppida saab
programmeerides. Kesktee foo-bar näidete ja reaalse elu näidete vahel on ehk mingid „programmeerimise
ülesannete kogud”. Üks selline on ka Eestis väljastatud -
"Programmeerimise eksamiülesannete kogu", Tartu 2007,
autoreiks Helle Hein, Jüri Kiho, Reimo Palm, Eno Tõnisson.
Võtan
siit ühe näite, mille varalt saab läbi kapata mõned põhilised konstruktsioonid
PS-s.
Edaspidigi kasutan sealt näiteid (ka omale näpuharjutuseks).
Ülesanne ja programmitekst
(mis ei pretendeeri mitte mingis mõttes mingi õppeteksti
või etaloni tiitlile, kuid mis siiski peaks töötama).
# Programmeerimise eksamiülesannete kogu 1
# On antud täisarvujärjendid poisid.txt ja tydrukud.txt,
olgu näiteks arvud antud komadega eraldatuna,
# Moodustada tantsupaarid kõige pikem poiss kõige pikema
tüdrukuga etc...
# Kui sugude vahel valitseb arvuline ebavõrdsus, jäävad
kõige pikemad poisid või tüdrukuid paariliseta.
# Väljastada lähteandmed, tantsupaarid ja paariliseta
jäänud poiste või tüdrukute pikkused.
$poisidAndmed = Get-Content "poisid.txt"
$tydrukudAndmed = Get-Content "tydrukud.txt"
"Poiste pikkused:"
$poisidAndmed
"Tüdrukute pikkused:"
$tydrukudAndmed
$poisid = $poisidAndmed -split "," | sort
-descending
$tydrukud = $tydrukudAndmed -split "," | sort
-descending
$diff = $poisid.count - $tydrukud.count
if ($diff -gt 0)
{
$pyle =
$poisid[0..($diff -1)]
$poisid = $poisid[($diff)..($poisid.count -
1)];
}
elseif ($diff -lt
0)
{
$tyle =
$tydrukud[0..(-$diff -1)]
$tydrukud =
$tydrukud[(-$diff)..($tydrukud.count - 1)];
}
# Paarid
$paarid = 0..($poisid.count -1)
foreach ($i in $paarid) {$paarid[$i] = "(" +
$poisid[$i] + ", " + $tydrukud[$i]+")"}
# Väljastus:
"Tantsupaarid on:"
$paarid -join " "
if ($diff -gt 0)
{
"Paarilisteta
jäid poisid pikkustega"
$pyle -join
", "
}
elseif ($diff -lt
0)
{
"Paarilisteta
jäid tüdrukud pikkustega"
$tyle -join
", "
}
Märkusi:
E1.
$poisidAndmed = Get-Content "poisid.txt"
Muutuja tunnus on dollar, nagu näiteks ka bashis, mida ehk
natuke võiks pidada PS eellaseks.
Nagu skriptivates keeltes ikka, võib muutuja sisu olla
suvaline ja seda ei pea ette teadma, mis sorti see võiks olla.
Muutuja võib sisaldada ühte või mitut objekti. Mitut objekti
sisaldavad muutujad on kas paisktabelid, sõnastikud (hash table, dictionary), ühe indeksi
järgi saab leida objekti, mis selle indeksi taga peitub, või massiivid (array).
Massiivide indeksiks on täisarv ja indekseerimine algab 0-st.
Get-Content loeb faili sisu (ekraanile või
muutujasse) – DOS type analoog ning käsk omabki aliast type.
KUI failis on üks rida, siis sisaldab muutuja ainsa
objektina seda rida ja ei ole massiiv.
Kui failis on mitu rida, siis tekib massiiv. Olgu failis tekst.txt mitu rida.
$tekst =
type tekst.txt
Nüüd faili esimene rida on $tekst[0], teine rida $tekst[1] … etc
NB PS kari!
KUI on aga ainult üks rida, siis massiivi ei teki, ja $tekst[0] on selle faili ainsa rea esimene täht!
See ongi praegu just nii, ülesande lihtsuse tõttu ongi vaid
üks rida andmeid (pikkused).
Korralikumas programmis, kus ette ei või teada, on seal
null, üks või mitu rida, tuleb tulem ümber lõigata massiiviks. Massiiviks
ümberlõikamise operaator on
@()
Peaaegu alati (see ülesanne ehk on erand) tasub faili
lugemist teha nii:
$poisid
= @(type poisid.txt)
Nüüd
$poisid.count / või $poisid.length ,
vastavalt maitsele on faili ridade arv. See on ka nii siis, kui failis
pole ühtegi rida.
Näide, mis võiks veenda, et ka tühja faili ridade arvu
näidatakse korrektselt:
(format-custom (fc) siin formaadib tühjust ja suunab
väljundi ümber faili)
Touch PS-s ei toimi.
PS C:\bat\power\PROGYL> fc >proov.txt
PS C:\bat\power\PROGYL> $proov = @(type proov.txt)
PS C:\bat\power\PROGYL> $proov.count
0
Küllaltki tõenäoliselt langete siin programmeerijate
hierarhias kategooriasse 'F', nagu minagi, kellel tuli selle
teadasaamiseks see viga läbi teha (kuigi manuaalis oli ju kõik kirjas, oops).
E2.
$poisidAndmed
väljastab
muutuja sisu ekraanile, ei pea echo-tama, nagu DOS-s.
>,
>> ümbersuunamise operaatorid toimivad nagu alati, kõik saab ümber
suunata faili.
(Allpool sellest veel
-gt operaatori juures, mis ehk natukene selgitab > ja < operaatorite mittetoimimist
tavalistes avaldistes)
E3.
$poisid = $poisidAndmed -split "," | sort
-descending
-split jagab sõne massiiviks, siin on eraldajaks
koma. Muuseas, alati on tulemus massiiv erinevalt Get-Content karist.
Seda ka siis, kui sõne sees koma ei olegi, siis on massiivis üks element.
-join teeb vastupidist, leiate programmi lõpus ka seda kasutava rea.
E4. if ($diff -gt 0)
<>
märke
võrldusoperatsioonides PS ei tunnista. Põhjuseks on nende sümbolite kasutamine
PS-s ümbersuunamistel.
Õnneks on loobutud MS täiesti iseäralikest operaatoritest
DOS puhul ning kasutatakse samu operaatoreid, mis näiteks Perlis ka toimivid.
Niisiis:
-ge suurem võrdne
-gt suurem kui
-lt vähem kui
-le vähem või
võrdne
Neid operaatoreid on veel, aga
praeguseks piisab. Kui operaatoritele ette kirjutada c, siis on võrdlused
sõnede puhul
tõstutundetud, i ette kirjutamine ei
muuda (s.t. võrdlus on tõstutundetu, aga perfektsionistid eelistavad täpset
kirjaviisi, siis peaks olema selgem, et võrdlus ei arvesta tähe tõstu.
Probleemiks nende võrdluste puhul on see, et need on jälle üldisest süsteemist väljas. Aga kesta skriptivate keelte puhul ongi asjad tavaliselt isemoodi. Võrreldes DOS-ga asjad vähemalt toimivad.
Probleemiks nende võrdluste puhul on see, et need on jälle üldisest süsteemist väljas. Aga kesta skriptivate keelte puhul ongi asjad tavaliselt isemoodi. Võrreldes DOS-ga asjad vähemalt toimivad.
E5. Tüübid
Õige on programmis teha nii:
[int[]] $poisid = [int[]]
($poisidAndmed -split ",") | sort -descending
[int[]] $tydrukud = [int[]]
($tydrukudAndmed -split ",") | sort -descending
Tähelepanelik lugeja kindlasti märkas,
et võrdlustes ei olnud mingit juttu tüüpidest. Selline lohakas stiil
skriptimisel ei ole siiski väga shokeeriv. Kui väga ei ole vaja, tüüpidega ei
armastata jahmerdada.
Õigem siiski oleks see asi korda panna.
Üleval olen $poisid massiivi jaoks selgeks teinud, et need ON täisarvud.
Seda, et tegemist on massiiviga ütleb [].
Ka vahepealses operatsioonis, kus
sisendandmeid tuli alles massiiviks jagada, tuleb enne sortimist öelda, et
sordi täisarve, mitte näiteks sõnesid, mis annavad valed tulemid.
PS enamasti üritab aru saada, mida
programmi looja tahab, aga ta ei saa alati aru. Ja tüübi määratlemine ütleb
vaid seda, et omistuse järel üritatakse vastav tüübiteisendus ära teha. Kui see
ei õnnestu, tulevad veateated. Aga näiteks
int tüüpi muutujale omistada väärtus
'012' ei ole mingi probleem, sellest saab vaikimisi arv 12.
Võrdlustes aga teisendatakse enne
võrdlust tüübid ära.
Kui tüübid on võrdluses erinevad,
määrab tüübiteisenduse ESIMENE operand.
Nii et kui kogemata on esimene operand
arvu 12 asemel '12' (see ütleb selgelt, et siin ON sõne), siis teine operand
lõigutakse ümber sõneks ja võrreldakse sõnesid.
E6. If üldkuju:
if ()
{}
elseif
{} …
else
{}
{} tähistab käsuplokki. Loogelised sulud
peavad if järel olema. Nii ei saa, et if järel tuleb üks avaldis ilma
looksulgudeta. Ka see avaldis peab olema
loogeliste sulgudega ümbritsetud.
E7. Massiivide tekitamine ja massiividest elementide
võtmine indeksioperatsioonide abiga.
Vaatleme programmis ettetulnud lauseid, kus massiividega
opereerimine käib:
$pyle =
$poisid[0..($diff -1)]
$poisid =
$poisid[($diff)..($poisid.count - 1)];
$tyle =
$tydrukud[0..(-$diff -1)]
$tydrukud =
$tydrukud[(-$diff)..($tydrukud.count - 1)];
# Paarid
$paarid = 0..($poisid.count -1)
Alustaksin lõpust:
K..N operatsioon tekitab PS-s täisarvude
massiivi, kus esimene element on K ja viimane N.
Praegu on see rida lihtsalt paaride massiiv
initsialiseerimiseks ja väga mugav oli sinna lihtsalt kirjutada juba ette
indeksid.
[] sisse kirjutatakse
massiivi indeksid, et vastavaid elemente kätte saada. Neid võib olla mitu. Indeksid
võivad ise moodustada massiivi. Millegipärast massiivi lõikumine väiksemaks
toimib just nii (ei ole paremat meetodit).
$poisid = $poisid[($diff)..($poisid.count - 1)];
Sama trikiga tuleb massiivist elemente välja loopida, kopeerides vaid need elemendid, mida vaja.
Sama trikiga tuleb massiivist elemente välja loopida, kopeerides vaid need elemendid, mida vaja.
$hei =@()
teeb massiivi
tühjaks.
Nüüd
Nüüd
PS C:\bat\power> $hei[0]=5
Array assignment failed because index '0' was out of
range.
At line:1 char:6
+ $hei[ <<<< 0]=5
+
CategoryInfo : InvalidOperation:
(0:Int32) [], RuntimeException
+
FullyQualifiedErrorId : IndexOutOfRange
annab veateate.
Väljastada massiivi
piiridest väljas elemente saab (väljastatakse tühi väärtus
$NULL )
Indeksid võivad olla ka negatiivsed, siis käib loendamine
lõpust, -1 on viimane element.
Seetõttu tüdrukute massiivi indeksi negatiivse väärtuse
korral võib saada ootamatuid tulemeid, mitte veateate massiivi piiride
ületamise kohta.
Silumise käigus juhtus see, et muutuja $diff jäi
negatiivseks ja sain imelikud tulemid.
Vahemiku (range) operaator K..N ei ole siiski kõige parem
meetod massiivi lihtsaks initsialiseerimiseks.
Kuid veel hullem meetod oleks alata tühjast massiivist ja siis elemente juurde liita.
Kuid veel hullem meetod oleks alata tühjast massiivist ja siis elemente juurde liita.
Näiteks:
PS
C:\bat\power\progyl> $hei=@()
PS
C:\bat\power\progyl> $hei +="hoi"
PS C:\bat\power\progyl>
$hei += (1,2,3)
PS
C:\bat\power\progyl> $hei
hoi
1
2
3
See töötab väikeste massiivide jaoks, aga suurte massiivide
puhul peab arvestama, et IGA elemendi liitmise korral tehakse massiivist uus
koopia ja see on tohutult ebaefektiivne.
Jälle üks väike kivi PS kapsaaeda (mis õnneks ei tee asju
siiski võimatuks, aga neid on vaja teada).
Nii et kui massiivi mõõtmed on ette teada (ja kui ka ei ole,
aga maks mõõde on teada), initsialiseerige massiiv ära ja ärge kasutage
tsüklites massiivide liitmist või massiividele elementide liitmist.
Parimat meetodit massivi alginitsialiseerimiseks vaatan
allpool, kui foreach tsükli asendame parema variandiga (selle ülesande puhul).
E7. Foreach ja for tsükkel
# Paarid
$paarid = 0..($poisid.count -1)
foreach ($i in $paarid) {$paarid[$i] =
"(" + $poisid[$i] + ", " + $tydrukud[$i]+")"}
Foreach
tsükkel on üsna isedokumenteeriv - $i
käib läbi kõik $paarid väärtused. See
on sageli mugavam, kui ise õiendada tsüklimuutujatega ja neile ühte juurde
liita.
Tsükli kiiruse
mõttes ei ole siiski nii praegu kõige prem.
$paarid võiks lihtsalt initsialiseerida ühe väärtusega
ja kasutada for tsüklit.
Õigem oleks
nende 2 rea asemel kirjutada:
$paarid =
@("") * ($poisid.count)
for ($i=0 ; $i -lt
$poisid.count; $i++)
{ $paarid[$i] =
"(" + $poisid[$i] + ", " + $tydrukud[$i]+")"}
For tsükli 3 osa on
alginitsialiseerimine ($i saab 0 –ks),
tsükli jätkamise tingmus ning tsükli lõpu /uue alustuse eelne operatsioon, mis
tavaliselt liidab $i-le 1 juurde.
.....
Mitu liigutust on juures, tsükliloendur, mida foreachis pole
vaja, tuleb algväärtustada, üks juurde liita, kontrollida piire.
PUHH. Selleks
pühapäevaks aitab.
PS -st aga veel isu täis saanud ei ole (erinevalt DOS-st), nii et jätkan millalgi.
0 Comments:
Postita kommentaar
<< Home