Powershell में scopes के बारे में

Aug 24 2020

मैं Powershell में scopes के बारे में सीख रहा हूं और कुछ प्रश्न हैं:

  1. "स्थानीय स्कोप" के बारे में: मैंने जो पढ़ा है, उससे स्थानीय स्कोप हमेशा वर्तमान स्कोप होता है। इसलिए, डिफ़ॉल्ट रूप से, जब हम एक आइटम बनाते हैं (स्कोप मॉडिफ़ायर के बिना), उदाहरण के लिए, एक चर, कुछ स्कोप में, इसे स्क्रिप्ट या ग्लोबल होने दें, स्कोप तदनुसार स्क्रिप्ट / ग्लोबल होगा। तो मेरा सवाल यह है: हमें localसंशोधक को स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता कब होगी ?
  2. MSDN कहता है:

आप एक स्क्रिप्ट या फ़ंक्शन चलाकर, एक सत्र बनाकर या पावरशेल का एक नया उदाहरण शुरू करके एक नया दायरा बना सकते हैं। जब आप एक नया स्कोप बनाते हैं, तो परिणाम एक पेरेंट स्कोप (मूल गुंजाइश) और एक चाइल्ड स्कोप (आपके द्वारा बनाया गया स्कोप) होता है। ...
जब तक आप स्पष्ट रूप से आइटम को निजी नहीं बनाते हैं, तब तक माता-पिता के दायरे में मौजूद आइटम बच्चे के दायरे के लिए उपलब्ध हैं। हालाँकि, आइटम जो आप बनाते हैं और चाइल्ड स्कोप में बदलते हैं, पेरेंट स्कोप को प्रभावित नहीं करते हैं, जब तक आप आइटम बनाते समय स्कोप को स्पष्ट रूप से निर्दिष्ट नहीं करते हैं।

लेकिन जब मैं निम्नलिखित कोशिश करता हूं:

PS> $Name = "John" PS> Powershell.exe PS>echo $Name  // No Output

ऊपर दिए गए उद्धरण से ऐसा लगता है कि "शक्तियां का एक नया उदाहरण शुरू करना" एक बच्चा गुंजाइश है, इसलिए माता-पिता के दायरे में सभी आइटम वहां दिखाई देनी चाहिए। कोई समझा सकता है?

जवाब

2 mklement0 Aug 24 2020 at 23:16

IRon के सहायक उत्तर के पूरक के लिए :

  1. [...] हमें स्थानीय संशोधक को स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता कब होगी?

$local:शायद ही कभी आवश्यकता होती है , क्योंकि स्थानीय गुंजाइश एक स्कोप स्पेसियर की अनुपस्थिति में निहित है।

हालांकि, कि केवल लागू होता है अगर संदर्भित चर वास्तव में एक के रूप में मौजूद स्थानीय चर , यह देखते हुए कि PowerShell के गतिशील scoping से चर बनाता पैतृक (पैरेंट) वंशज (बच्चे) को दिखाई scopes के साथ-साथ scopes (देखें इस उत्तर में अधिक जानकारी के लिए):

  • उदाहरण के लिए, मान लें कि आपने वैश्विक दायरे $foo = 'bar'में घोषित किया है , फिर एक स्क्रिप्ट में उल्लेख करते हुए पहले एक स्थानीय उदाहरण की तलाश करेंगे ; यदि कोई नहीं है, तो पैतृक (माता-पिता) दायरे में परिभाषित किया जाता है, यदि कोई हो, जो इस उदाहरण में वैश्विक होगा , और वापस आ जाएगा।$foo $foo$foo $foo'bar'

  • इसके विपरीत, यदि, आपकी स्क्रिप्ट में, आप उपयोग करते हैं $local:foo, एक स्थानीय $fooचर को परिभाषित किए बिना , आप या तो $nullडिफ़ॉल्ट रूप से प्राप्त करते हैं या, यदि Set-StrictMode -Version 2या उच्चतर प्रभाव में है, तो एक बयान -त्रुटि उत्पन्न होती है।


  1. MSDN कहता है: [...] एक सत्र बनाकर, या PowerShell का एक नया उदाहरण शुरू करके [...] इसका परिणाम एक पैरेंट स्कोप (मूल स्कोप) और एक चाइल्ड स्कोप (आपके द्वारा बनाया गया स्कोप) है।

प्रलेखन है गलत इस लेखन (एक के रूप में इस संबंध में GitHub मुद्दे दायर की गई है):

  • पैतृक बच्चों के बीच पैतृक (माता-पिता) रिश्ते केवल एक दिए गए सत्र (रनस्पेस) के संदर्भ में मौजूद हैं ।

    • यह है, डायनेमिक स्कूपिंग - पैतृक स्कोप से चर और अन्य परिभाषाओं की दृश्यता - केवल दिए गए सत्र के भीतर स्कोप पर लागू होती है।

    • एक उल्लेखनीय अपवाद है कि कार्यों है एक मॉड्यूल से करते नहीं बुला दायरे से एक बच्चे को दायरे में चलाने - को छोड़कर अगर उस दायरे बुला होने वाला वैश्विक दायरा; मॉड्यूल के अपने स्वयं के स्कोप डोमेन (तकनीकी रूप से सेशन स्टेट्स ) होते हैं जो केवल वैश्विक स्कोप से जुड़े होते हैं - चर्चा के लिए इस GitHub डॉक्स मुद्दे को देखें ।

  • इसलिए, कॉलिंग स्कोप का कोई भी चाइल्ड स्कोप निम्न परिदृश्यों में नहीं बनाया जाता है, जहाँ नए लॉन्च किए गए कोड को कॉलिंग स्कोप में वेरिएबल्स (और अन्य परिभाषाओं) का कुछ भी पता नहीं है :

    • PowerShell रीमोटिंग (जैसे, साथ ) या के माध्यम से एक नया सत्र शुरू करनाEnter-PSSessionInvoke-Command -Computer

    • एक शुरू पृष्ठभूमि [धागा] काम के साथ Start-Jobया Start-ThreadJobया के साथ समानांतर में धागे चल ForEach-Object -Parallelv7.0 + में

    • PowerShell CLI ( PowerShell [Core] के लिए, Windows PowerShell के लिए) का उपयोग करके एक नया PowerShell उदाहरण (प्रक्रिया) शुरू करना ।pwshpowershell.exe

    • इन परिदृश्यों में कॉलिंग स्कोप से नए लॉन्च किए गए कोड तक मूल्यों को संप्रेषित करने के लिए, स्पष्ट कार्रवाई की आवश्यकता है :

      • सीएलआई का उपयोग करते समय या उपयोग करते समय Start-Job, जहां एक ही मशीन पर एक बच्चे की प्रक्रिया बनाई जाती है, केवल कॉलिंग प्रक्रिया में परिभाषित पर्यावरण चर स्वचालित रूप से बच्चे की प्रक्रिया के लिए उपलब्ध हो जाते हैं ।
      • अन्यथा, कॉलर से मानों को तर्क के रूप में पारित किया जाना चाहिए या - सीएलआई का उपयोग करते समय छोड़कर - $using:गुंजाइश के माध्यम से - इस उत्तर को देखें ।
4 iRon Aug 24 2020 at 14:48

बाद वाले सवाल से शुरू:

स्कोप फ़ंक्शंस और इनवॉल्ड स्क्रिप्ट (cmdlets) के साथ खेलते हैं, जैसे:

Function Test {
    $Test++ Write-Host 'Local:' $Test
}
$Test = 5 Test Write-Host 'Global:' $Test

रिटर्न:

Local: 6
Global: 5

तथा:

Function Test {
    $Global:Test++ Write-Host 'Local:' $Test
}
$Test = 5 Test Write-Host 'Global:' $Test

रिटर्न:

Local: 6
Global: 6

या यदि आप फ़ंक्शन को स्क्रिप्ट में रखते हैं (उदाहरण के लिए MyScript.ps1):

$Test = 5 .\MyScript.ps1 Write-Host $Test # $Test is unaffected unless you use the $Global scope in your script

जब तक आप मूल रूप से उसी परिणाम को वापस नहीं करेंगे, जब तक कि आप अपनी स्क्रिप्ट को डॉट-सोर्स नहीं करते हैं जहां यह वर्तमान दायरे में चलेगा:

$Test = 5 . .\MyScript.ps1 Write-Host $Test # $Test might be affected by MyScript.ps1 if you just use $Test

आप जो कर रहे हैं, उसके लिए:
आप एक पूर्ण नया पावरशेल सत्र (के साथ Powershell.exe) बना रहे हैं, जो कि चर की एक नई सूची के साथ शुरू होगा।
यहां ध्यान दें कि यदि आप exitनए सत्र से प्रारंभिक चर फिर से देखेंगे :

PS C:\> $Name = "John" PS C:\> Powershell.exe Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. Try the new cross-platform PowerShell https://aka.ms/pscore6 PS C:\> Write-Host 'New session' $Name
New session
PS C:\> Exit
PS C:\> Write-Host 'Initial session' $Name
Initial session John

जो पहले प्रश्न के संबंध में है, मुझे नहीं लगता कि ऐसे कई अनुप्रयोग हैं जहां आपको स्पष्ट रूप से $Localगुंजाइश का उल्लेख करने की आवश्यकता है, लेकिन आपको एक उदाहरण देने के लिए जहां आप इसका उपयोग कर सकते हैं:

$Test = 5 Function Test { Write-Host ($Local:Test++)
}
Test

यदि आप स्पष्ट रूप से गुंजाइश का उपयोग करते हैं (वास्तव में आप एक खाली स्थानीय चर के साथ शुरू करेंगे जो ) के साथ उपरोक्त उदाहरण में संयुक्त वेतन वृद्धि ऑपरेटर शुरू हो जाएगा और यदि आप उस दायरे से बाहर निकल जाते हैं जहां आप चर की एक प्रति प्राप्त करेंगे । पैरेंट स्कोप।0$Local05$Local$Test