كيف تؤثر النطاقات على برامج PowerShell النصية
في البرامج النصية الدفعية ، يكون للتغييرات في متغيرات البيئة تأثيرًا عالميًا على الجلسة الحالية بشكل افتراضي. بالنسبة إلى PowerShell ، فإن العكس هو الصحيح لأن النطاقات تستخدم لعزل تعديلات البرنامج النصي. هنا ، سوف نستكشف كيف تؤثر النطاقات على البرامج النصية لـ PowerShell وكيفية العمل داخلها وحولها.
ما هو النطاق?
في PowerShell ، يشير "النطاق" إلى البيئة الحالية التي يعمل فيها برنامج نصي أو shell command. يتم استخدام النطاقات لحماية بعض الكائنات داخل البيئة من تعديلها عن غير قصد بواسطة نصوص أو وظائف. بشكل خاص ، تتم حماية الأشياء التالية من التعديل بواسطة الأوامر التي يتم تشغيلها من نطاق آخر ، ما لم يتم تحديدها بخلاف المعلمات في تلك الأوامر:
- المتغيرات
- اسماء مستعارة
- المهام
- محركات أقراص PowerShell (PSDrives)
يتم إنشاء نطاقات جديدة كلما قمت بتشغيل برنامج نصي أو وظيفة ، أو عند إنشاء جلسة عمل جديدة أو مثيل PowerShell. النطاقات التي تم إنشاؤها بواسطة تشغيل البرامج النصية والدوال لها علاقة "أصل / طفل" مع النطاق الذي تم إنشاؤه منها. هناك عدد قليل من النطاقات التي لها معاني خاصة بشكل خاص ، ويمكن الوصول إليها بالاسم:
- ال عالمي النطاق هو النطاق الذي يتم إنشاؤه عند بدء تشغيل PowerShell. وهو يتضمن المتغيرات ، والأسماء المستعارة ، والوظائف ، و PSDrives المضمنة في PowerShell بالإضافة إلى أي متغيرات يتم إجراؤها بواسطة ملف تعريف PowerShell الخاص بك..
- ال محلي يشير النطاق إلى أي نطاق حالي. عند بدء تشغيل PowerShell سيشير إلى النطاق العالمي ، في إطار البرنامج النصي سيكون نطاق البرنامج النصي ، إلخ.
- ال النصي يتم إنشاء النطاق عند تشغيل برنامج نصي. الأوامر الوحيدة التي تعمل ضمن هذا النطاق هي تلك الموجودة في البرنامج النصي.
- نشر يمكن تعريف النطاقات داخل النطاق الحالي ، لمنع الأوامر في النطاقات الأخرى من القدرة على قراءة أو تعديل العناصر التي قد يكون لديهم إمكانية الوصول إليها.
يمكن أيضًا الإشارة إلى النطاقات برقم في أوامر معينة ، حيث يشار إلى النطاق الحالي على أنه صفر ويتم الإشارة إلى أسلافه عن طريق زيادة الأعداد الصحيحة. على سبيل المثال ، في إطار نص برمجي من النطاق العالمي ، سيكون نطاق البرنامج النصي 0 ، ويكون النطاق العالمي 1. ويكون النطاق الذي تم تداخله بشكل أكبر داخل نطاق البرنامج النصي ، مثل الدالة ، يشير إلى النطاق العالمي باعتباره 2. لن تعمل الأرقام السالبة للإشارة إلى نطاقات الطفل - سيظهر سبب ذلك قريبًا.
كيف تؤثر النطاقات على الأوامر
وكما ذكرنا سابقًا ، فإن الأوامر التي يتم تنفيذها في نطاق واحد لن تؤثر على الأشياء في نطاق آخر ما لم يتم إخبارها على وجه التحديد بذلك. على سبيل المثال ، إذا كان $ MyVar موجودًا في النطاق العالمي ويقوم أحد البرامج النصية بتشغيل أمر لتعيين $ MyVar إلى قيمة مختلفة ، فسيظل الإصدار العالمي من $ MyVar بدون تغيير بينما يتم وضع نسخة من $ MyVar في نطاق البرنامج النصي الجديد القيمة. في حالة عدم وجود $ MyVar ، سيقوم البرنامج النصي بإنشائه داخل نطاق البرنامج النصي بشكل افتراضي - وليس في النطاق العالمي. من المهم أن تتذكر عندما تتعرف على علاقة الوالد / الطفل الفعلية بين النطاقات.
العلاقة الأصل / التابع للنطاقات في PowerShell هي اتجاه واحد. يمكن للأوامر أن ترى ، وتعديل اختياريا ، النطاق الحالي ، الأم ، وأي نطاقات فوق ذلك. ومع ذلك ، لا يمكنهم رؤية أو تعديل الأشياء في أي أطفال من النطاق الحالي. ويرجع ذلك في المقام الأول إلى أنه بمجرد الانتقال إلى نطاق الأصل ، تم بالفعل تدمير نطاق الطفل لأنه قد تم تحقيق غرضه. على سبيل المثال ، لماذا يجب عليك رؤية أو تعديل متغير في نطاق البرنامج النصي ، من النطاق العالمي ، بعد إنهاء البرنامج النصي؟ هناك الكثير من الحالات التي تحتاج فيها إلى تغييرات في البرنامج النصي أو الوظيفة لتستمر بعد الانتهاء منها ، ولكن ليس هناك الكثير من الأماكن التي تحتاج فيها إلى إجراء تغييرات على الكائنات داخل نطاق البرنامج النصي أو الوظيفة قبل أو بعد تشغيلها. (عادة ، سيتم التعامل مع هذه الأشياء كجزء من البرنامج النصي أو الوظيفة نفسها على أي حال.)
بالطبع ، ما هي القواعد دون استثناء؟ استثناء واحد لما سبق هو نطاقات خاصة. لا يمكن الوصول إلى الكائنات في النطاقات الخاصة إلا للأوامر التي يتم تشغيلها في النطاق الذي تم إنشاؤه منها. استثناء هام آخر هو العناصر التي تحتوي على خاصية AllScope. هذه متغيرات خاصة وأسماء مستعارة سيؤثر تغييرها في أي نطاق على جميع النطاقات. ستوضح لك الأوامر التالية المتغيرات والأسماء المستعارة التي تحتوي على خاصية AllScope:
الحصول على المتغير | Where-Object $ _. Options -match 'AllScope' Get-Alias | Where-Object $ _. Options -match 'AllScope')
النطاقات في العمل
لإلقاء نظرة أولى على النطاقات في العمل ، سنبدأ في جلسة PowerShell حيث تم تعيين المتغير $ MyVar على سلسلة ، "أنا متغير عالمي!" ، من سطر الأوامر. بعد ذلك ، سيتم تشغيل البرنامج النصي التالي من ملف يسمى Scope-Demo.ps1:
الوظيفة FunctionScope 'Changing $ MyVar with a function.' $ MyVar = 'لقد تم ضبطها من خلال وظيفة!' "MyVar يقول $ MyVar" "التحقق من القيمة الحالية لـ $ MyVar." "MyVar يقول $ MyVar" "تغيير $ MyVar بالنص." $ MyVar = 'تم ضبطه بواسطة برنامج نصي! "MyVar تقول $ MyVar" "FunctionScope" التحقق من القيمة النهائية لـ MyVar قبل إنهاء البرنامج النصي. " "MyVar يقول $ MyVar" "
إذا كانت البرامج النصية PowerShell تعمل بنفس طريقة البرامج النصية ، فإننا نتوقع أن تتحول قيمة $ MyVar (أو٪ MyVar٪ في بناء الجملة) إلى تغيير من 'I am a variable variable!' ، إلى 'لقد تم تعيينها بواسطة برنامج نصي!' ، وأخيرا إلى "لقد تم تعيينها من قبل وظيفة!" حيث ستبقى حتى تتغير صراحة مرة أخرى أو يتم إنهاء الجلسة. ومع ذلك ، انظر ما يحدث بالفعل هنا ونحن نتحرك من خلال كل من النطاقات - لا سيما ، بعد أن أكملت وظيفة FunctionScope عملها ونقوم بفحص المتغير مرة أخرى من البرنامج النصي ، وفيما بعد النطاق العالمي.
كما ترى ، يبدو أن المتغير يتغير عندما نتحرك من خلال النص البرمجي لأنه ، إلى أن تكتمل وظيفة FunctionScope ، كنا نتحقق من المتغير من نفس النطاق الذي تم تغييره فيه لآخر مرة. بعد أن تم تنفيذ FunctionScope على الرغم من ذلك ، عدنا إلى نطاق البرنامج النصي حيث تم ترك $ MyVar دون مساس بالدالة. ثم ، عندما انتهى البرنامج النصي ، عدنا إلى النطاق العالمي حيث لم يتم تعديله على الإطلاق.
الوصول خارج النطاق المحلي
لذلك ، كل هذا جيد وجيد لمساعدتك على الابتعاد عن تطبيق التغييرات التي تطرأ على البيئة خارج نطاق النصوص والوظائف الخاصة بك ، ولكن ماذا لو كنت ترغب بالفعل في إجراء مثل هذه التعديلات؟ هناك بنية خاصة ، وبسيطة إلى حد ما ، لإنشاء وتعديل الكائنات خارج النطاق المحلي. عليك فقط وضع اسم النطاق في بداية اسم المتغير ، ووضع نقطتين بين النطاق وأسماء المتغيرات. مثله:
$ العمومية: MyVar $ script: MyVar $ local: MyVar
يمكنك استخدام هذه المعدلات على حد سواء عند عرض وتحديد المتغيرات. دعونا نرى ما يحدث مع هذا البرنامج النصي العرض التوضيحي:
الدالة FunctionScope "تغيير $ MyVar في نطاق الوظيفة المحلية ..." $ local: MyVar = "هذا هو MyVar في النطاق المحلي للوظيفة." "تغيير $ MyVar في نطاق البرنامج النصي ... '$ script: MyVar =' MyVar اعتاد أن يكون تعيين بواسطة برنامج نصي. الآن تعيين بواسطة دالة. "تغيير $ MyVar في النطاق العالمي ..." $ العمومية: MyVar = 'تم تعيين MyVar في النطاق العالمي. الآن تعيين بواسطة وظيفة. "التحقق من $ MyVar في كل نطاق ..." المحلي: $ local: MyVar "" Script: $ script: MyVar "" Global: $ global: MyVar "" "الحصول على القيمة الحالية $ MyVar." "MyVar يقول $ MyVar" "تغيير $ MyVar بالنص." $ MyVar = 'تم ضبطه بواسطة برنامج نصي! "MyVar تقول $ MyVar" FunctionScope "التحقق من $ MyVar من نطاق البرنامج النصي قبل الخروج." "MyVar يقول $ MyVar" "
كما كان من قبل ، سنبدأ بتحديد المتغير في النطاق العالمي وننتهي بالتحقق من نتيجة النطاق العالمي النهائية.
هنا يمكنك رؤية أن FunctionScope كان قادراً على تغيير المتغير في نطاق البرنامج النصي ، واستمرار التغييرات بعد اكتماله. أيضا ، استمر التغيير إلى المتغير في النطاق العالمي حتى بعد خروج البرنامج النصي. يمكن أن يكون هذا مفيدًا بشكل خاص إذا كان عليك تغيير المتغيرات في نص برمجي بشكل متكرر ، أو ضمن النطاق العالمي ، باستخدام الشفرة نفسها - ما عليك سوى تحديد وظيفة أو نص مكتوب لتعديل المتغير في مكان وكيفية القيام به ، و ندعو ذلك كلما كانت تلك التغييرات ضرورية.
كما ذكرنا سابقًا ، يمكن أيضًا استخدام أرقام النطاق في أوامر معينة لتعديل المتغير على مستويات مختلفة فيما يتعلق بالنطاق المحلي. إليك نفس البرنامج النصي المستخدم في المثال الثاني أعلاه ، ولكن مع تعديل الوظيفة لاستخدام أوامر Get-Variable و Set-Variable مع أرقام النطاق بدلاً من الرجوع إلى المتغير مباشرةً باستخدام النطاقات المسماة:
الدالة FunctionScope "تغيير $ MyVar في النطاق 0 ، نسبة إلى FunctionScope… 'Set-Variable MyVar" هذا هو MyVar في نطاق الدالة 0. "-Scope 0' تغيير $ MyVar في النطاق 1 ، بالنسبة إلى FunctionScope… 'Set-Variable تم تغيير MyVar "MyVar في النطاق 1 ، من دالة." -نطاق 1 "تغيير $ MyVar في النطاق 2 ، نسبة إلى Functionscope ... تم تغيير MyVar" متغير - متغير MyVar في النطاق 2 ، من وظيفة. " -Scope 2 "التحقق من $ MyVar في كل نطاق ..." نطاق 0: 'Get-Variable MyVar -Scope 0 -ValueOnly' نطاق 1: 'Get-Variable MyVar -Scope 1 -ValueOnly' نطاق 2: 'Get-Variable MyVar -Scope 2 -ValueOnly "" الحصول على القيمة الحالية لـ $ MyVar. " "MyVar يقول $ MyVar" "تغيير $ MyVar بالنص." $ MyVar = 'تم ضبطه بواسطة برنامج نصي! "MyVar تقول $ MyVar" FunctionScope "التحقق من $ MyVar من نطاق البرنامج النصي قبل الخروج." "MyVar يقول $ MyVar" "
على غرار ما سبق ، يمكننا أن نرى هنا كيف يمكن للأوامر في نطاق واحد تعديل الكائنات في نطاقها الأصلي.
معلومة اضافية
لا يزال هناك الكثير الذي يمكن القيام به مع نطاقات مما يمكن احتواؤه في هذه المقالة. تؤثر النطاقات على أكثر من متغيرات فقط ، ولا يزال هناك الكثير الذي يمكن تعلمه عن النطاقات الخاصة ومتغيرات AllScope. لمزيد من المعلومات المفيدة ، يمكنك تشغيل الأمر التالي من داخل PowerShell:
الحصول على مساعدة حول_scopes
ملف المساعدة نفسه متاح أيضًا على TechNet.
نطاق الصورة: spadassin على openclipart