Hogyan befolyásolja a hatókörök a PowerShell parancsfájlokat
A kötegfájlokban a környezeti változók változása alapértelmezés szerint globális hatással van az aktuális munkamenetre. A PowerShell esetében a pontos ellenkezője igaz, mert a hatókörök a script módosításainak elkülönítésére szolgálnak. Itt fogjuk megvizsgálni, hogy a hatókörök hogyan befolyásolják a PowerShell szkripteket, és hogyan dolgozhatnak rajtuk és körülöttük.
Mi az a hatókör?
A PowerShell-ben a „hatókör” arra a környezetre utal, amelyben egy parancsfájl vagy parancs shell működik. A hatókörök arra szolgálnak, hogy megvédjék a környezetben lévő bizonyos objektumokat a szkriptek vagy funkciók véletlen módosításától. Különösen a következő dolgokat védik a módosításoktól a parancsoktól, amelyek egy másik hatókörből indulnak ki, kivéve, ha a parancsok másképpen határozzák meg:
- változók
- Más nevek
- Funkciók
- PowerShell meghajtók (PSDrives)
Új szkópokat hoz létre, amikor parancsfájlt vagy funkciót futtat, vagy amikor új munkamenetet vagy PowerShell példányt hoz létre. A szkriptek és funkciók futtatásával létrehozott hatókörök „szülő / gyermek” viszonyban vannak a hatókörrel, ahonnan létrehozták őket. Van néhány olyan terület, amelyeknek különleges jelentősége van, és név szerint hozzáférhetők:
- A Globális a hatókör a PowerShell indításakor létrehozott hatókör. Magában foglalja a PowerShellbe beépített változókat, álneveket, függvényeket és PSDrive-ket, valamint azokat, amelyeket a PowerShell profilja készített.
- A Helyi hatálya a jelenlegi hatókörre vonatkozik. Amikor elindítja a PowerShell-et, a globális hatókörre vonatkozik, egy szkripten belül a parancsfájl hatóköre lesz.
- A Forgatókönyv a hatókör akkor jön létre, ha egy parancsfájl fut. Az egyetlen olyan parancs, amely ezen a területen működik, a parancsfájlban található.
- Magán a hatókörök meghatározhatók az aktuális hatókörön belül, hogy megakadályozzák, hogy más területeken lévő parancsok képesek legyenek olvasni vagy módosítani azokat az elemeket, amelyekkel egyébként hozzáférhetnek.
A hatókörök számok szerint is jelennek meg bizonyos parancsokban, ahol az aktuális hatókört nullának nevezik, és őseit a növekvő egész számok hivatkozzák. Például a Globális hatókörből futó parancsfájlban a Script hatókör 0 lenne, és a globális hatókör 1 lenne. A Script hatókörön belül további beágyazott hatókör, például egy függvény, a globális hatókörre vonatkozna, mint 2 A negatív számok azonban nem fognak működni a gyermekkötelezettségre hivatkozva - ennek oka hamarosan nyilvánvaló lesz.
Hogyan befolyásolja a hatókörök parancsokat
Amint azt korábban említettük, az egy hatókörben végrehajtott parancsok nem befolyásolják a más hatóköröket, kivéve, ha erre kifejezetten meg kell mondani. Ha például a $ MyVar létezik a globális hatókörben, és egy parancsfájl parancsot futtat a $ MyVar más értékre történő beállítására, akkor a $ MyVar globális verziója változatlan marad, amíg a $ MyVar másolatát az új érték. Ha a $ MyVar nem létezik, a parancsfájl alapértelmezés szerint létrehozza a Script hatókörön belül - nem a globális hatókörben. Ez fontos megjegyezni, amikor megtanulod a szülők / szülők közötti tényleges kapcsolatot.
A PowerShell-ben a hatókörök szülő / gyermek kapcsolata egyirányú. A parancsok láthatják, és adott esetben módosíthatják az aktuális alkalmazási területet, a szülőjét, és minden fent említett területet. Ugyanakkor nem láthatnak vagy módosíthatnak semmilyen gyermeket az aktuális hatókörben. Ez elsősorban azért van, mert ha már a szülői körbe költözött, a gyermek hatókörét már elpusztították, mert teljesítette a célját. Például, miért kell látnia vagy módosítania egy változót a Script hatókörben a globális hatókörből, miután a szkript leállt? Rengeteg olyan eset van, amikor a parancsfájl vagy a funkció változásai megmaradnak a befejezését követően, de nem annyira sok, ahol a parancsfájl vagy a funkció hatókörébe tartozó objektumok módosítására van szükség a futás előtt vagy után. (Általában az ilyen dolgokat a szkript részeként kezeli, vagy egyébként is működni fog.)
Természetesen mi a szabályok kivétel nélkül? A fentiek közül az egyik kivétel a Magántulajdonságok. A privát körökben lévő objektumok csak azokon a parancsokon érhetők el, amelyek a létrehozott hatókörben futnak. Egy másik fontos kivétel az AllScope tulajdonságú elemek. Ezek olyan speciális változók és álnevek, amelyeknek bármely hatályának megváltoztatása minden hatókört érint. A következő parancsok megmutatják, hogy mely változók és álnevek vannak az AllScope tulajdonsággal:
Get-Variable | Hol-Objektum $ _. Beállítások -másolás 'AllScope' Get-Alias | Hol-Objektum $ _. Opciók -másolás 'AllScope')
Alkalmazási körök
Első pillantásunkban a hatóköröket egy PowerShell-munkamenetben kezdjük, ahol a $ MyVar változó karakterláncra lett állítva: 'Én globális változó vagyok!', A parancssorból. Ezután a következő script fut a Scope-Demo.ps1 nevű fájlból:
Funkció Funkciócope $ MyVar módosítása egy funkcióval. ” $ MyVar = 'Beállítottam egy funkcióval!' "MyVar szerint $ MyVar" "A $ MyVar aktuális értékének ellenőrzése." "MyVar azt mondja, hogy $ MyVar" "$ MyVar módosítása szkriptrel." $ MyVar = 'Beállítottam egy szkript!' "MyVar azt mondja, $ MyVar" "FunctionScope" A MyVar végső értékének ellenőrzése a szkript kilépés előtt. " "MyVar szerint $ MyVar" "
Ha a PowerShell szkriptek ugyanúgy működtek, mint a kötegfájlok, akkor a $ MyVar (vagy a% MyVar% -os kötegelt szintaxisban) völgyéből az "Én vagyok a globális változó!" , és végül a "Beállítottam egy funkcióval!" ahol addig maradna, amíg újra nem változtatja meg, vagy a munkamenet megszűnik. Azonban, nézzük meg, mi történik itt, amikor áthaladunk minden egyes hatókörön - különösen, miután a FunctionScope függvény befejezte a munkáját, és újra megnézzük a változót a Script-ből, majd a globális, hatókörből.
Amint láthatjuk, a változó változik, amikor átmentünk a szkripten, mert addig, amíg a FunctionScope függvény befejeződött, a változót ugyanazon hatókörön belül ellenőriztük. Miután a FunctionScope-t mégis elvégezték, visszatértünk a Script-körbe, ahol a $ MyVar-t a funkció érintetlenül hagyta. Ezután, amikor a szkript megszűnt, visszajöttünk a globális körbe, ahol egyáltalán nem módosították.
Elérése a helyi körön kívül
Tehát ez minden jó és jó, hogy segítsen abban, hogy véletlenül ne alkalmazzuk a környezetet a szkripteken és a függvényeken túl, de mi van, ha valóban ilyen módosításokat szeretne tenni? Van egy speciális és meglehetősen egyszerű szintaxis a helyi hatókörön kívüli objektumok létrehozására és módosítására. Csak adja meg a hatókör nevét a változó neve elején, és helyezzen egy kettőspontot a hatókör és a változó nevek közé. Mint ez:
$ global: MyVar $ script: MyVar $ local: MyVar
Ezeket a módosítókat használhatja a változók megtekintésekor és beállításakor. Lássuk, mi történik ezzel a demonstrációs szkriptrel:
Funkció Funkciócope $ MyVar módosítása a helyi függvénykörnyezetben ... ”$ local: MyVar =" Ez a funkció helyi tartományában a MyVar. "'$ MyVar módosítása a szkript hatókörében ...' $ script: MyVar = 'MyVar Most egy függvény által beállítva. "$ MyVar módosítása a globális hatókörben ..." $ global: MyVar = 'A MyVar a globális hatókörben lett beállítva. "$ MyVar ellenőrzése minden egyes területen ..." "Helyi: $ local: MyVar" "Script: $ script: MyVar" "Globális: $ global: MyVar" "" A $ MyVar aktuális értékének elérése. " "MyVar azt mondja, hogy $ MyVar" "$ MyVar módosítása szkriptrel." $ MyVar = 'Beállítottam egy szkript!' "A MyVar azt mondja, hogy a $ MyVar" FunctionScope "A $ MyVar ellenőrzése a parancsfájl hatóköréről a kilépés előtt." "MyVar szerint $ MyVar" "
Mint korábban, elkezdjük a változót a globális hatókörben, és végül a végső globális hatókör eredményének ellenőrzésével végezni.
Itt láthatja, hogy a FunctionScope képes volt megváltoztatni a változót a Script hatókörben, és a módosítások befejezése után is fennmaradnak. A változó változása a globális hatókörben még a szkript kilépése után is fennállt. Ez különösen akkor hasznos lehet, ha a változókat egy szkripten belül vagy a globális hatókörön belül ismételten meg kell változtatnia, ugyanazzal a kóddal - csak olyan függvényt vagy parancsfájlt definiálhat, amely a változó módosítására íródott, és ahol szükség van rá, és felhívja ezt a kérdést, amikor ezek a változtatások szükségesek.
Amint azt korábban említettük, bizonyos parancsokban a hatókörszámok is használhatók a változó különböző szinteken történő módosítására a helyi hatókörre vonatkozóan. Ugyanaz a parancsfájl, amelyet a fenti második példában használtunk, de azzal a funkcióval, amely a Get-Variable és Set-Variable parancsok használatával módosítja a hatókörszámokat, ahelyett, hogy közvetlenül a változót a nevezett hatókörökkel hivatkozná:
Funkció Funkciócope "$ MyVar változása 0-ban a FunctionScope-hoz képest ..." Set-Variable MyVar "Ez a MyVar a függvény 0-ában." -Szám: '$ MyVar módosítása az 1. hatókörben a FunctionScope… -hoz képest' 'Set-Variable A MyVar MyVar-t az 1. hatókörben megváltoztatták egy függvényből. ' -Szcope 1 '$ MyVar módosítása a 2. területen, a Functionscope-hoz képest ...' A Set-Variable MyVar 'MyVar-ot a 2. körben megváltoztattuk egy függvényből.' 2. sz. "$ MyVar ellenőrzése minden hatókörben ..." 0: 0-as érték: 'Get-Variable MyVar -Scope 0 -ValueOlyly' 1. kör: 'Get-Variable MyVar -Scope 1 -ValueOnly' Scope 2: 'Get-Variable MyVar -Scope 2 -ValueOnly "" A $ MyVar aktuális értékének elérése. " "MyVar azt mondja, hogy $ MyVar" "$ MyVar módosítása szkriptrel." $ MyVar = 'Beállítottam egy szkript!' "A MyVar azt mondja, hogy a $ MyVar" FunctionScope "A $ MyVar ellenőrzése a parancsfájl hatóköréről a kilépés előtt." "MyVar szerint $ MyVar" "
Az előzőekhez hasonlóan itt láthatjuk, hogy az egyik hatókörben lévő parancsok módosíthatják a szülői hatókörben lévő objektumokat.
további információ
Még ennél is sokkal többet lehet elvégezni, mint amennyit belefér a cikkbe. A hatókörök több mint a változókat érintik, és még többet kell megtanulni a magánkörnyezetről és az AllScope változókról. További hasznos információkért a következő parancsot futtathatja a PowerShell-en belül:
Get-Help about_scopes
Ugyanez a súgófájl is elérhető a TechNet-en.
Scope image credit: a spadassin opencliparton