โฮมเพจ » ทำอย่างไร » ขอบเขตมีผลกับสคริปต์ PowerShell อย่างไร

    ขอบเขตมีผลกับสคริปต์ PowerShell อย่างไร

    ในสคริปต์แบบแบตช์การเปลี่ยนแปลงตัวแปรสภาพแวดล้อมมีผลกระทบระดับโลกต่อเซสชันปัจจุบันโดยค่าเริ่มต้น สำหรับ PowerShell สิ่งที่ตรงกันข้ามนั้นเป็นจริงเนื่องจากขอบเขตถูกใช้เพื่อแยกการแก้ไขสคริปต์ ที่นี่เราจะสำรวจว่าขอบเขตมีผลกับสคริปต์ PowerShell อย่างไรและทำงานอย่างไรและรอบ ๆ พวกเขาอย่างไร.

    ขอบเขตคืออะไร?

    ใน PowerShell“ ขอบเขต” หมายถึงสภาพแวดล้อมปัจจุบันซึ่งสคริปต์หรือเชลล์คำสั่งทำงานอยู่ ขอบเขตถูกใช้เพื่อปกป้องวัตถุบางอย่างภายในสภาพแวดล้อมจากการแก้ไขโดยไม่ได้ตั้งใจโดยสคริปต์หรือฟังก์ชั่น โดยเฉพาะอย่างยิ่งสิ่งต่อไปนี้ได้รับการปกป้องจากการแก้ไขโดยคำสั่งที่เรียกใช้จากขอบเขตอื่นเว้นแต่จะระบุไว้เป็นอย่างอื่นโดยพารามิเตอร์ในคำสั่งเหล่านั้น:

    • ตัวแปร
    • นามแฝง
    • ฟังก์ชั่น
    • ไดรฟ์ PowerShell (PSDrives)

    ขอบเขตใหม่จะถูกสร้างขึ้นทุกครั้งที่คุณเรียกใช้สคริปต์หรือฟังก์ชันหรือเมื่อคุณสร้างเซสชันหรืออินสแตนซ์ใหม่ของ PowerShell ขอบเขตที่สร้างขึ้นโดยการเรียกใช้สคริปต์และฟังก์ชั่นมีความสัมพันธ์“ parent / child” กับขอบเขตที่สร้างขึ้น มีขอบเขตไม่กี่ข้อที่มีความหมายพิเศษเป็นพิเศษและสามารถเข้าถึงได้โดยใช้ชื่อ:

    • ทั่วโลก scope คือขอบเขตที่สร้างขึ้นเมื่อ PowerShell เริ่มทำงาน มันรวมถึงตัวแปรนามแฝงฟังก์ชั่นและ PSDrives ที่มีอยู่แล้วใน PowerShell เช่นเดียวกับที่ทำโดยโปรไฟล์ PowerShell ของคุณ.
    • ในประเทศ scope หมายถึงอะไรก็ตามที่ขอบเขตปัจจุบันคือ เมื่อคุณเริ่ม PowerShell มันจะอ้างถึงขอบเขตทั่วโลกภายในสคริปต์มันจะเป็นขอบเขตสคริปต์ ฯลฯ.
    • ต้นฉบับ ขอบเขตถูกสร้างขึ้นเมื่อสคริปต์ทำงาน คำสั่งเดียวที่ทำงานภายในขอบเขตนี้คือคำสั่งที่อยู่ในสคริปต์.
    • เอกชน ขอบเขตสามารถกำหนดได้ภายในขอบเขตปัจจุบันเพื่อป้องกันคำสั่งในขอบเขตอื่นไม่สามารถอ่านหรือแก้ไขรายการที่พวกเขาอาจเข้าถึงได้.

    ขอบเขตยังสามารถอ้างถึงตามจำนวนในคำสั่งบางอย่างโดยที่ขอบเขตปัจจุบันจะถูกอ้างถึงเป็นศูนย์และบรรพบุรุษของมันถูกอ้างอิงโดยการเพิ่มจำนวนเต็ม ตัวอย่างเช่นภายในสคริปต์ที่รันจากขอบเขตโกลบอลขอบเขตสคริปต์จะเป็น 0 และขอบเขตโกลบอลจะเป็น 1 ขอบเขตที่ซ้อนกันเพิ่มเติมภายในขอบเขตสคริปต์เช่นฟังก์ชันจะอ้างถึงขอบเขตโกลบอลเป็น 2 ตัวเลขเชิงลบจะไม่สามารถใช้อ้างอิงขอบเขตเด็กได้ - เหตุผลนี้จะปรากฏในไม่ช้า.

    ขอบเขตมีผลต่อคำสั่งอย่างไร

    ดังที่ได้กล่าวไว้ก่อนหน้านี้คำสั่งที่ดำเนินการภายในขอบเขตหนึ่งจะไม่ส่งผลกระทบต่อสิ่งต่าง ๆ ในขอบเขตอื่นเว้นแต่ได้รับคำสั่งให้ทำ ตัวอย่างเช่นหาก $ MyVar มีอยู่ในขอบเขตส่วนกลางและสคริปต์เรียกใช้คำสั่งเพื่อตั้งค่า $ MyVar ให้เป็นค่าอื่นเวอร์ชัน Global ของ $ MyVar จะยังคงไม่เปลี่ยนแปลงในขณะที่สำเนา $ MyVar จะถูกวางไว้ในขอบเขตสคริปต์ด้วยใหม่ ราคา. หาก $ MyVar ไม่มีอยู่สคริปต์จะสร้างขึ้นภายในขอบเขตสคริปต์โดยค่าเริ่มต้น - ไม่อยู่ในขอบเขตส่วนกลาง สิ่งนี้เป็นสิ่งสำคัญที่ต้องจำในขณะที่คุณเรียนรู้เกี่ยวกับความสัมพันธ์ระหว่างผู้ปกครอง / ลูกจริงระหว่างขอบเขต.

    ความสัมพันธ์แม่ / ลูกของขอบเขตใน PowerShell เป็นแบบทางเดียว คำสั่งสามารถดูและแก้ไขทางเลือกขอบเขตปัจจุบันพาเรนต์และขอบเขตใด ๆ ข้างต้น อย่างไรก็ตามพวกเขาไม่สามารถมองเห็นหรือแก้ไขสิ่งต่าง ๆ ในขอบเขตลูกปัจจุบัน สิ่งนี้เป็นหลักเพราะเมื่อคุณย้ายเข้าสู่ขอบเขตหลักขอบเขตของลูกนั้นถูกทำลายไปแล้วเพราะมันบรรลุวัตถุประสงค์แล้ว ตัวอย่างเช่นทำไมคุณต้องดูหรือแก้ไขตัวแปรในขอบเขตสคริปต์จากขอบเขตส่วนกลางหลังจากสคริปต์สิ้นสุดลง มีหลายกรณีที่คุณต้องการการเปลี่ยนแปลงของสคริปต์หรือการทำงานเพื่อคงอยู่นอกเหนือความสมบูรณ์ แต่ไม่มากนักที่คุณจะต้องทำการเปลี่ยนแปลงวัตถุภายในขอบเขตของสคริปต์หรือฟังก์ชั่นก่อนหรือหลังมันจะทำงาน (โดยปกติสิ่งต่าง ๆ จะถูกจัดการเป็นส่วนหนึ่งของสคริปต์หรือฟังก์ชั่นของตัวเองต่อไป)

    แน่นอนกฎอะไรโดยไม่มีข้อยกเว้น? หนึ่งข้อยกเว้นด้านบนคือขอบเขตส่วนตัว วัตถุในขอบเขตส่วนตัวนั้นสามารถเข้าถึงได้เฉพาะกับคำสั่งที่ทำงานในขอบเขตที่พวกเขาถูกสร้างขึ้น ข้อยกเว้นที่สำคัญอีกข้อหนึ่งคือรายการที่มีคุณสมบัติ AllScope นี่คือตัวแปรพิเศษและชื่อแทนที่การเปลี่ยนแปลงในขอบเขตใด ๆ จะมีผลกับขอบเขตทั้งหมด คำสั่งต่อไปนี้จะแสดงให้คุณเห็นว่าตัวแปรและชื่อแทนใดมีคุณสมบัติ AllScope:

    รับตัวแปร | ตำแหน่งที่วัตถุ $ _. ตัวเลือก - จับคู่ 'AllScope' รับนามแฝง | จุดที่วัตถุ $ _. ตัวเลือก - จับคู่ 'AllScope')

    ขอบเขตในการดำเนินการ

    สำหรับการดูครั้งแรกของเราในขอบเขตของการดำเนินการเราจะเริ่มต้นในเซสชัน PowerShell ซึ่งตัวแปร $ MyVar ถูกตั้งค่าเป็นสตริง 'ฉันเป็นตัวแปรทั่วโลก!' จากบรรทัดคำสั่ง จากนั้นสคริปต์ต่อไปนี้จะถูกเรียกใช้จากไฟล์ชื่อ Scope-Demo.ps1:

    Function FunctionScope 'การเปลี่ยน $ MyVar ด้วยฟังก์ชั่น' $ MyVar = 'ฉันถูกตั้งค่าโดยฟังก์ชั่น!' "MyVar พูดว่า $ MyVar" "กำลังตรวจสอบค่าปัจจุบันของ $ MyVar ' "MyVar พูดว่า $ MyVar" "การเปลี่ยน $ MyVar ด้วยสคริปต์ ' $ MyVar = 'ฉันได้รับสคริปต์!' "MyVar พูดว่า $ MyVar" "FunctionScope" กำลังตรวจสอบค่าสุดท้ายของ MyVar ก่อนที่สคริปต์จะออก ' "MyVar พูดว่า $ MyVar" "

    หากสคริปต์ PowerShell ทำงานเหมือนกับชุดสคริปต์เราคาดหวังว่า $ MyVar (หรือ% MyVar% ในรูปแบบแบทช์) จะเปลี่ยนจาก 'ฉันเป็นตัวแปรทั่วโลก!' เป็น 'ฉันตั้งค่าโดยสคริปต์!' และในที่สุดก็ถึง 'ฉันถูกตั้งค่าโดยฟังก์ชั่น!' จะอยู่ที่ไหนจนกว่าจะมีการเปลี่ยนแปลงอย่างชัดเจนอีกครั้งหรือสิ้นสุดเซสชัน อย่างไรก็ตามดูสิ่งที่เกิดขึ้นจริงที่นี่เมื่อเราเลื่อนผ่านแต่ละขอบเขต - โดยเฉพาะอย่างยิ่งหลังจากฟังก์ชั่น FunctionScope เสร็จสิ้นการทำงานและเราตรวจสอบตัวแปรอีกครั้งจากสคริปต์และหลังจากนั้นขอบเขตทั่วโลก.

    ในขณะที่คุณสามารถเห็นตัวแปรดูเหมือนว่าจะเปลี่ยนแปลงในขณะที่เราย้ายผ่านสคริปต์เพราะจนกระทั่งฟังก์ชั่น FunctionScope เสร็จสมบูรณ์เรากำลังตรวจสอบตัวแปรจากภายในขอบเขตเดียวกับที่มีการเปลี่ยนแปลงครั้งล่าสุด หลังจาก FunctionScope เสร็จแล้วเราก็ย้ายกลับเข้าไปในขอบเขตของสคริปต์ที่ $ MyVar ถูกทิ้งไว้โดยฟังก์ชัน จากนั้นเมื่อสคริปต์สิ้นสุดลงเราก็กลับเข้าสู่ขอบเขตของโลกซึ่งไม่ได้ทำการแก้ไขเลย.

    การเข้าถึงภายนอกขอบเขตท้องถิ่น

    ดังนั้นนี่คือทั้งหมดที่ดีและดีที่จะช่วยให้คุณหลีกเลี่ยงการใช้การเปลี่ยนแปลงกับสภาพแวดล้อมโดยไม่ได้ตั้งใจนอกเหนือไปจากสคริปต์และฟังก์ชั่นของคุณ แต่ถ้าหากคุณต้องการแก้ไขเช่นนั้น มีไวยากรณ์ที่พิเศษและเรียบง่ายสำหรับการสร้างและแก้ไขวัตถุที่อยู่นอกเหนือขอบเขตท้องถิ่น คุณเพียงแค่ใส่ชื่อขอบเขตที่จุดเริ่มต้นของชื่อตัวแปรและใส่เครื่องหมายโคลอนระหว่างชื่อขอบเขตและชื่อตัวแปร อย่างนี้:

    $ global: MyVar $ script: MyVar $ local: MyVar

    คุณสามารถใช้โมดิฟายเออร์เหล่านี้ได้ทั้งเมื่อดูและตั้งค่าตัวแปร มาดูกันว่าเกิดอะไรขึ้นกับสคริปต์สาธิตนี้:

    ฟังก์ชั่น FunctionScope "การเปลี่ยน $ MyVar ในขอบเขตฟังก์ชั่นท้องถิ่น ... '$ local: MyVar =" นี่คือ MyVar ในขอบเขตของฟังก์ชั่นท้องถิ่น "' การเปลี่ยน $ MyVar ในขอบเขตสคริปต์… '$ script: MyVar =' MyVar กำหนดโดยสคริปต์ตอนนี้ตั้งค่าโดยฟังก์ชั่น "การเปลี่ยน $ MyVar ในขอบเขตทั่วโลก ... '$ global: MyVar =' MyVar ถูกกำหนดไว้ในขอบเขตส่วนกลาง ตอนนี้ตั้งค่าโดยฟังก์ชัน "กำลังตรวจสอบ $ MyVar ในแต่ละขอบเขต… '" Local: $ local: MyVar "" สคริปต์: $ script: MyVar "" Global: $ global: MyVar "" "รับค่าปัจจุบันของ $ MyVar' "MyVar พูดว่า $ MyVar" "การเปลี่ยน $ MyVar ด้วยสคริปต์ ' $ MyVar = 'ฉันได้รับสคริปต์!' "MyVar พูดว่า $ MyVar" FunctionScope 'กำลังตรวจสอบ $ MyVar จากขอบเขตสคริปต์ก่อนที่จะออก' "MyVar พูดว่า $ MyVar" "

    ก่อนหน้านี้เราจะเริ่มต้นด้วยการตั้งค่าตัวแปรในขอบเขตส่วนกลางและสิ้นสุดด้วยการตรวจสอบผลลัพธ์ขอบเขตโลกรอบสุดท้าย.

    ที่นี่คุณจะเห็นว่า FunctionScope สามารถเปลี่ยนตัวแปรในขอบเขตสคริปต์และมีการเปลี่ยนแปลงที่ยังคงอยู่หลังจากเสร็จสิ้น นอกจากนี้การเปลี่ยนแปลงตัวแปรในขอบเขตสากลยังคงอยู่แม้ว่าสคริปต์จะออกแล้ว สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณต้องเปลี่ยนตัวแปรซ้ำ ๆ ภายในสคริปต์หรือภายในขอบเขตส่วนกลางโดยใช้รหัสเดียวกันคุณเพียงแค่กำหนดฟังก์ชั่นหรือสคริปต์ที่เขียนขึ้นเพื่อปรับเปลี่ยนตัวแปรที่คุณต้องการทำและอย่างไร เรียกร้องให้มีการเปลี่ยนแปลงเมื่อใดก็ตามที่จำเป็น.

    ตามที่ระบุไว้ก่อนหน้านี้หมายเลขขอบเขตสามารถใช้ในคำสั่งบางอย่างเพื่อปรับเปลี่ยนตัวแปรที่ระดับต่าง ๆ ที่เกี่ยวข้องกับขอบเขตภายใน นี่เป็นสคริปต์เดียวกับที่ใช้ในตัวอย่างที่สองด้านบน แต่ด้วยฟังก์ชันที่ปรับเปลี่ยนเพื่อใช้คำสั่ง Get-Variable และ Set-Variable พร้อมหมายเลขขอบเขตแทนการอ้างอิงตัวแปรโดยตรงด้วยขอบเขตที่มีชื่อ:

    Function FunctionScope "การเปลี่ยน $ MyVar ในขอบเขต 0 สัมพันธ์กับ FunctionScope ... 'Set-Variable MyVar" นี่คือ MyVar ในขอบเขตของฟังก์ชัน 0 "-Scope 0' การเปลี่ยน $ MyVar ในขอบเขต 1 เมื่อเทียบกับ FunctionScope ... 'Set-Variable MyVar 'MyVar ถูกเปลี่ยนในขอบเขต 1 จากฟังก์ชัน' -Scope 1 'การเปลี่ยน $ MyVar ในขอบเขต 2 ซึ่งเกี่ยวข้องกับ Functioncope ... ' MyVar ที่ตั้งค่าได้แบบแปรปรวน 'MyVar ถูกเปลี่ยนในขอบเขต 2 จากฟังก์ชัน' -Scope 2 "การตรวจสอบ $ MyVar ในแต่ละขอบเขต ... " ขอบเขต 0: 'MyVar ที่รับค่าได้ -Scope 0 -ValueOnly' ขอบเขต 1: 'MyVar รับค่าได้ -Scope 1 -ValueOnly' ขอบเขต 2: 'Get-Variable MyVar -Scope 2 -ValueOnly "" รับค่าปัจจุบันของ $ MyVar ' "MyVar พูดว่า $ MyVar" "การเปลี่ยน $ MyVar ด้วยสคริปต์ ' $ MyVar = 'ฉันได้รับสคริปต์!' "MyVar พูดว่า $ MyVar" FunctionScope 'กำลังตรวจสอบ $ MyVar จากขอบเขตสคริปต์ก่อนที่จะออก' "MyVar พูดว่า $ MyVar" "

    ก่อนหน้านี้เราจะเห็นว่าคำสั่งในขอบเขตหนึ่งสามารถปรับเปลี่ยนวัตถุในขอบเขตหลักได้อย่างไร.

    ข้อมูลเพิ่มเติม

    ยังมีอีกมากมายที่สามารถทำได้ด้วยขอบเขตที่เกินกว่าที่จะพอดีกับบทความนี้ ขอบเขตมีผลกระทบมากกว่าแค่ตัวแปรและยังมีสิ่งที่ต้องเรียนรู้เพิ่มเติมเกี่ยวกับขอบเขตส่วนตัวและตัวแปร AllScope สำหรับข้อมูลที่เป็นประโยชน์เพิ่มเติมคุณสามารถเรียกใช้คำสั่งต่อไปนี้จากภายใน PowerShell:

    รับความช่วยเหลือ about_scopes

    ไฟล์ช่วยเหลือเดียวกันนี้มีอยู่ใน TechNet เช่นกัน.


    ขอบเขตภาพเครดิต: spadassin บน openclipart