Powershell: هل حان الوقت لـ "PowerShell vZeroTechnicalDebt" و / أو آلية الاشتراك في ميزات جديدة / ثابتة تحطم التوافق مع الإصدارات السابقة؟

تم إنشاؤها على ٢٦ أبريل ٢٠١٨  ·  69تعليقات  ·  مصدر: PowerShell/PowerShell

لاحظ أن مصطلح "الديون الفنية" يستخدم هنا بشكل فضفاض ليعني "السلوك المتراكم المتراكم الذي لا يمكن إصلاحه دون كسر التوافق مع الإصدارات السابقة" ؛


_Update_: بدأrjmholt رسميًا مناقشة حول كيفية تنفيذ وإدارة التغييرات العاجلة: # 13129.


ملاحظة: هذه المشكلة ، التي نشأت من https://github.com/PowerShell/PowerShell/issues/5551#issuecomment -380522712 ، هي فقط لبدء المناقشة لمعرفة ما إذا كانت هناك رغبة أساسية في قبول

لقد خدم التزام PowerShell الثابت بالتوافق مع الإصدارات السابقة المجتمع جيدًا على مر السنين.

على الجانب الآخر ، كان الناتج الثانوي الذي لا مفر منه هو تراكم الديون التقنية التي تتطلب حفظ استثناءات وتشكل حاجزًا أمام الوافدين الجدد.

لا يمكن حل بعض المشكلات الأساسية الموجودة اليوم إلا على حساب التوافق مع الإصدارات السابقة ، وهناك طريقتان - غير متعارضتين - للتعامل مع ذلك:

  • تنفيذ إصدار "PowerShell vZeroTechnicalDebt" الذي يتخلص من جميع الديون التقنية ، ولكنه يفقد التوافق مع الإصدارات السابقة (ربما مع الإصدارات المستقبلية باستخدام الإصدار الدلالي للإشارة إلى التوافق)

  • دمج ميزات / إصلاحات كسر التوافق مع الإصدارات السابقة في قاعدة التعليمات البرمجية الحالية ، والمتاحة بشكل صارم على أساس _opt-in_ فقط.

ما هي الأساليب ، إن وجدت ، التي نحن على استعداد للنظر فيها؟
بمجرد توضيح ذلك ، يمكننا تجسيد العمليات.

فيما يلي بعض المشكلات الأساسية الحالية التي لا يمكن حلها إلا على حساب التوافق مع الإصدارات السابقة ؛ أنا متأكد من أن الآخرين سيفكرون في المزيد:

بيانات البيئة

مكتوب اعتبارًا من:

PowerShell Core v6.0.2
Issue-Meta

التعليق الأكثر فائدة

هناك تكلفة لإصلاح المشكلات التي أعتقد أنها الدين الفني لشركة PowerShell وعدم اعتماد مفاهيم .NET الجديدة كما ظهرت

  • بناء جملة اللغة لمعلمات النوع لطرق الأدوية # 5146

  • يظهر دعم المحرك لـ Extension Methods تلقائيًا في نظام الكتابة (كما هو الحال في _اللغات المجمعة_ .Net). # 2226

  • دعم اللغة لواجهات برمجة التطبيقات غير المتزامنة # 6716 (و RFC )

هناك بعض الميزات المؤسفة:

  • يمكن أن نفعل شيئا استنادا على نوع تلميحات (مثلKirkMunro الصورة FormatPx ) بدلا من أوامر cmdlets أن الناتج تنسيق الأشياء؟ # 4594 # 4237 # 3886

  • هل يمكنك تطبيع مزود السجل ليكون على أساس المحتوى - بدلاً من الشعور وكأنه عرض توضيحي لكيفية عمل مزود الملكية؟ # 5444

  • هل يمكنك إعادة بناء PSProviders بعمق لتسهيل كتابتها؟ إنه لأمر مخز أن يستغرق الأمر طبقتين من التجريد للوصول إلى "SHiPS" وإعطاء الأشخاص أخيرًا طريقة لكتابة مقدمي الخدمة الذين يرغبون في استخدامها

ماذا عن سؤال أكبر:

هل سنكون على استعداد لإعادة النظر في نهج "العديد من الطرق أفضل" والعمل على نهج "حفرة النجاح"؟ أعني ، هل سنكون على استعداد لإزالة الميزات التي تعتبر "الطريقة السهلة" ولكنها أسوأ في الأساس ، لصالح وجود "الطريقة الصحيحة" فقط للقيام بالأشياء؟ على سبيل المثال:

  • جعل CmdletBinding قيد التشغيل دائمًا
  • جعل التدوين @ () يعني List[PSObject]
  • اجعل @ {} تعني Dictionary[PSObject, PSObject] (أو Dictionary[string, PSObject] 😲)
  • جعل _Process_ الكتلة الافتراضية
  • ربما تجعل _ValueFromPipelineByPropertyName_ الافتراضي ؛-)

ال 69 كومينتر

مثير للإعجاب. لطالما تساءلت عن سبب استخدام 1 في .ps1 لإضافة نوع من الإصدارات الدلالية إلى نصوص PowerShell النصية ، مما يسمح للبرنامج النصي بتحديد ما إذا كان قد تم تكييفه مع التغييرات المحتملة.

هناك تكلفة لإصلاح المشكلات التي أعتقد أنها الدين الفني لشركة PowerShell وعدم اعتماد مفاهيم .NET الجديدة كما ظهرت

  • بناء جملة اللغة لمعلمات النوع لطرق الأدوية # 5146

  • يظهر دعم المحرك لـ Extension Methods تلقائيًا في نظام الكتابة (كما هو الحال في _اللغات المجمعة_ .Net). # 2226

  • دعم اللغة لواجهات برمجة التطبيقات غير المتزامنة # 6716 (و RFC )

هناك بعض الميزات المؤسفة:

  • يمكن أن نفعل شيئا استنادا على نوع تلميحات (مثلKirkMunro الصورة FormatPx ) بدلا من أوامر cmdlets أن الناتج تنسيق الأشياء؟ # 4594 # 4237 # 3886

  • هل يمكنك تطبيع مزود السجل ليكون على أساس المحتوى - بدلاً من الشعور وكأنه عرض توضيحي لكيفية عمل مزود الملكية؟ # 5444

  • هل يمكنك إعادة بناء PSProviders بعمق لتسهيل كتابتها؟ إنه لأمر مخز أن يستغرق الأمر طبقتين من التجريد للوصول إلى "SHiPS" وإعطاء الأشخاص أخيرًا طريقة لكتابة مقدمي الخدمة الذين يرغبون في استخدامها

ماذا عن سؤال أكبر:

هل سنكون على استعداد لإعادة النظر في نهج "العديد من الطرق أفضل" والعمل على نهج "حفرة النجاح"؟ أعني ، هل سنكون على استعداد لإزالة الميزات التي تعتبر "الطريقة السهلة" ولكنها أسوأ في الأساس ، لصالح وجود "الطريقة الصحيحة" فقط للقيام بالأشياء؟ على سبيل المثال:

  • جعل CmdletBinding قيد التشغيل دائمًا
  • جعل التدوين @ () يعني List[PSObject]
  • اجعل @ {} تعني Dictionary[PSObject, PSObject] (أو Dictionary[string, PSObject] 😲)
  • جعل _Process_ الكتلة الافتراضية
  • ربما تجعل _ValueFromPipelineByPropertyName_ الافتراضي ؛-)

كل الاقتراحات الرائعة ،Jaykul.

إعادة إنشاء رمز @() يعني List[PSObject] : أعتقد أنه يمكننا المضي قدمًا في هذا الأمر واستخدام نوع مجموعة قابل للتوسيع بكفاءة كنوع مجموعة PowerShell الأساسي ، بحيث يتم استخدامه في أي مكان [object[]] حاليًا (ويستخدم داخليًا وكذلك عند إرجاع المجموعات ، بدون عقوبة أداء تحويل النوع) ؛ هناك تحديات حول استخدام + ، لكن PetSerAl اقترحت تطبيق قائمة مخصصة للتعامل مع ذلك .

إعادة جعل Process {} الكتلة الافتراضية في الوظائف ، كنقطة جانبية: هذا ما يفعله Filter حاليًا ، لكنه يقتصر على - ضمنيًا - Process block ، ومتغير الوظيفة هذا على ما يبدو لم يتم القبض عليه أبدًا ؛ توحيد الاثنين في سياق Function أمر منطقي بالنسبة لي.

مضحك ، في مكالمة وضع الاستعداد لمجتمع Azure PowerShell الآن ، وسوف ينتقلون من AzureRm إلى وحدة Az جديدة عبر النظام الأساسي (لا يوجد AzureRm.Core منفصل) ، ومع تغيير جميع بادئات الأوامر من AzureRm إلى Az. سيكون الاثنان جنبًا إلى جنب لفترة من الوقت ، لكنهما ينتقلان إلى مجموعة الأوامر الجديدة.

سيئة للغاية لم تتح لـ PowerShell فرصة بعد لإنشاء ملف تنفيذي جديد يعمل جنبًا إلى جنب مع Windows PowerShell ، ولكن هذا قد ينفصل عن بعض العناصر القديمة التي تسحبه.

فقط تخيل ما سيحدث إذا ما سعينا لتحقيقه:
من الناحية الواقعية ، سيستغرق الأمر 6 أشهر على الأقل من الجهود المركزة للتوصل إلى نسخة "لا ندم عليها" و 6 أشهر أخرى لتكرارها. ثم تحتاج وحدات الطرف الثالث إلى التكيف معها أيضًا حتى يكون هذا الإصدار مفيدًا ، الأمر الذي سيستغرق 6 أشهر أخرى على الأقل للحصول على تغطية معقولة (وتذكر أن بعض الوحدات لن تفعل ذلك أبدًا) ... تأخير ومشاكل غير متوقعة ، إلخ ... لذا ، لا ، أعتقد أنه مجرد تمني أن يتخلص المرء من جميع الديون التقنية دفعة واحدة (مع الاستمرار في تطوير النسخة القديمة وليس مجرد الاحتفاظ بها).

بقدر ما كنت أتمنى وجود مثل هذه النسخة ، أعتقد أنه سيكون من الممكن فقط الوصول إليها ببطء مرة واحدة في كل مرة. مع الإصدار 6 ، تم بالفعل قبول الكثير من التغييرات العاجلة ، لكنني أعتقد أنه إذا تضمن أحدهم الكثير من التغييرات العاجلة في إصدار واحد ، فسيصبح من الصعب جدًا ترقية البرامج النصية / الوحدات النمطية الحالية. من الجيد مناقشة التغييرات الأكثر قيمة ولكن حتى لا يكون هناك إصدار LTS من pwsh ، لا أعتقد أن الوقت قد حان للتفكير في الحصول على مجموعة ثانية من pwsh مع المزيد من التغييرات الجوهرية بالتوازي مع الإصدار السائد الحالي.

تضمين التغريدة ومع ذلك ، حتى التغييرات الصغيرة نسبيًا على المسار الأساسي يمكن أن تعرقل بشكل خطير التبني. انظر إلى Python 3. لقد استغرق الأمر 10 _years_ للاستفادة منها. مع تغييرات أكبر بكثير ، من يدري كم من الوقت سيستغرق الأمر حتى تصبح لغة Perl 6 هي المهيمنة (واستغرق الأمر 15 عامًا للتوصل إلى الأشياء الصحيحة ، لذا يبدو أن لغة PHP لمدة 1.5 عامًا بالنسبة لـ PowerShell ++ متفائلة :-)) كسر الأشياء على أساس منتظم ، ربما بسبب الطريقة وما تستخدم من أجله.

Python 3 هو بالتأكيد عرض الرعب ، هل اشتعلت بالفعل حتى الآن؟ ما زلت أعمل 2.7 ، ولا أخطط للترقية في أي وقت قريبًا. لكنني لم أسمع الكثير عن بيرل 6 مؤخرًا أيضًا ...

أعتقد أن الدروس التي يجب تعلمها من Python هناك هي فصل التغييرات العاجلة على اللغة من تغيير الإصدار إلى المحرك. افتراضيًا ، لا يزال بإمكان محرك PS 7 تشغيل ملفات البرامج النصية السابقة (.PS1) في وضع تغييرات لا يمكن كسرها ، بينما إذا تم وضع علامة على البرنامج النصي على أنه 7 مدرك (على سبيل المثال بامتداد PS7) ، فيمكنهم إعلان أنه تم تحديثه _ و_ ذلك تتطلب PS 7 على الأقل للتشغيل. اتمنى ان يكون هذا منطقي

ربما تكون أفضل قصة نجاح هي JavaScript / TypeScript / Babel. يبدو المترجم (مع دعم خريطة المصدر) وكأنه الطريق الصحيح لتطور اللغة.

جافا سكريبت حالة خاصة. أنت عالق جدًا معها ، لذا فإن التحويل هو الخيار الوحيد حقًا. تعد كتابة النص عبارة عن جافا سكريبت "فقط" بامتدادات لذلك يسهل على الأشخاص اعتمادها. أي برنامج جافا سكريبت هو برنامج مطبوع ، لذا تبدأ بما لديك وإضافة التعليقات التوضيحية من هناك. من ناحية أخرى ، فإن Dart هي لغتها الخاصة ولكنها تنقل إما إلى جافا سكريبت أو وقت تشغيل أصلي في Chrome (على الأقل كانت هذه هي الخطة في وقت ما). لا يبدو أن Dart قد اكتسبت الكثير من التبني خارج Google ، على الأرجح لأنها لغتها الخاصة ..

تضمين التغريدة

Python 3 هو بالتأكيد عرض الرعب ، هل اشتعلت بالفعل حتى الآن؟

كنت أقرأ مقالًا الأسبوع الماضي حيث كان المؤلف يدعي أن الكتلة الحرجة قد تحققت لبايثون 3. أن جميع الوحدات الأساسية كانت متاحة والآن الناس يهاجرون بأعداد كبيرة. سوف نرى..

مثير للإعجاب. لطالما تساءلت عن سبب استخدام 1 في .ps1 لإضافة نوع من الإصدارات الدلالية إلى نصوص PowerShell النصية ، مما يسمح للبرنامج النصي بالإشارة إلى ما إذا كان قد تم تكييفه مع التغييرات المحتملة.

WRT .ps1 ، نحتفظ بالحق في تغيير الامتداد في حالة فهمنا للغة بشكل خاطئ تمامًا مما يؤدي إلى تغييرات كارثية في وقت التشغيل بحيث لا تعمل البرامج النصية للإصدار السابق. لكن تغيير الامتداد يؤدي أيضًا إلى كومة ضخمة من العمل لأن العديد من الأشياء في النظام البيئي مرتبطة بالامتداد. لذلك ليس من السهل القيام به. وبالطبع ، لكوننا جزءًا من Windows ، إذا قمنا بتشكيل الامتداد ، فلا يزال يتعين علينا الحفاظ على كلا الإصدارين (نوع مثل Python 2/3).

ههههههههه

اهتمامات صحيحة ولكن بروح:

من الجيد مناقشة أهم التغييرات العاجلة

يرجى مشاركة أي شيء قد يدور في ذهنك.

ببطء تغيير كسر واحد في كل مرة

على الرغم من أن آلية الاشتراك (المحددة معجمًا) للتغييرات غير المتوافقة تعد حلاً ، فإنني قلق بشأن شيئين:

  • يمكن أن يؤدي التقديم المتقطع إلى عدم قدرة أي شخص على تذكر الإصدار المطلوب لأي ميزة ؛ يتبادر إلى الذهن بيرل (v5-).

  • تصبح قاعدة الشفرة منتفخة ويصعب الحفاظ عليها ، ويتضخم الناتج الثنائي الناتج بشكل متساوٍ ، مما يضر (على الأقل) بأداء بدء التشغيل.

لقد قلتها من قبل: بالنسبة لي - وهذا مجرد حدس - كان الإصدار 6 GA بمثابة حل وسط مؤسف بين جعل كبار السن غير راضين عن تغيير التغييرات أثناء نقل ما يكفي من الأمتعة لإعاقة التبني في عالم Unix [- like].

بعد قولي هذا ، نظرًا لشباب PowerShell النسبي في عالم يونكس [- يشبه] ، ربما (لا يزال) هناك استعداد أكبر لحل المشكلات عن طريق التغييرات غير المتوافقة. كما تنص BrucePay ، يجب صيانة Windows PowerShell على أي حال ، ويمكن أن يظل الملاذ الآمن للتوافق مع الإصدارات السابقة.

أعتقد أن حجم النتائج السلبية لمثل هذه التغييرات الفاصلة قد تمت تغطيته بالفعل ، وأنا أتفق مع معظم تلك النقاط. أكتب هذا لأنني أشك في أن هذه التغييرات ، في السياق الأكبر ، ستعود بفوائد كبيرة في المقام الأول. على الأقل بالنسبة للطريقة التي أستخدم بها PowerShell.

يتضمن OP البيان التالي:

على الجانب الآخر ، كان الناتج الثانوي الذي لا مفر منه هو تراكم الديون التقنية التي تتطلب حفظ استثناءات وتشكل حاجزًا أمام الوافدين الجدد.

يبدو أن المنطلق الضمني لهذا البيان هو أن إجراء هذه التغييرات المتقطعة المختلفة من شأنه أن يخفف من عبء حفظ الاستثناءات. في الواقع سيكون ذلك نتيجة عظيمة. ومع ذلك ، فإنني أشك في أن تكون هذه هي النتيجة. سلوك PowerShell غني عن قصد. هذا يجعلها معبرة وغير متوقعة. يبدو أن التعبير والقدرة على التنبؤ يعملان ضد بعضهما البعض ، على الأقل بين اللغات التي أعرفها.

بينما أوافق على أن العديد من التغييرات العاجلة المذكورة أعلاه من شأنها تحسين القدرة على التنبؤ إلى حد ما في بعض الحالات ، فإن العديد من الجوانب غير المتوقعة والمفاجئة للغة ستبقى. على الرغم من قضاء سنوات في كتابة PowerShell ، ما زلت مندهشًا كثيرًا من سلوك PowerShell الذي يبدو أنه عن طريق التصميم وربما لا ينبغي تغييره. بعض الأمثلة الحديثة التي تتبادر إلى الذهن هي كما يلي:

  • ربط مؤجل مشروط لوسائط [scriptblock] (# 6419)
  • متى يحدث التعداد الضمني بالضبط (# 5832)
  • تحويل [AutomationNull]::Value إلى $null أثناء ربط المعلمة (# 6357 مرتبط)
  • تأثير break و continue على تدفق التحكم في خط الأنابيب (# 5811)
  • ماذا يحدث عندما تضرب $null ( SO )
  • كيف يؤثر استخدام كتل البرامج النصية عبر حالات الجلسة على $_ ( SO 1 ، SO 2 )

أتوقع أن هذه الأمثلة ليست سوى جزء صغير من العديد من الفروق الدقيقة الأخرى المصممة بعناية ولكن المفاجئة التي لم أكتشفها بعد. اخترت هذه الأمثلة لأن

  1. إنها تمثل سلوكًا ربما لا يمكن تحسينه في PowerShell و
  2. ليس لدي أي أمل في اكتشاف كل آثارها بشكل موثوق عند قراءة أو كتابة PowerShell.

أنا بخير مع هذا. الغالبية العظمى من سلوك PowerShell المفاجئ ليس له تأثير دائم على نجاحي مع PowerShell. غالبًا ما يتم اكتشاف السلوك المفاجئ على الفور عن طريق الاختبار أثناء التطوير. أتعلم من الأشياء التي تتسرب من خلالها وأستخدمها لتحسين استراتيجية الاختبار الخاصة بي. هذا صحيح سواء كانت تلك السلوكيات المفاجئة من النوع الذي يمكن القضاء عليه أو النوع الذي يجب أن يبقى.

سواء تم إجراء تغييرات التكسير المقترحة أعلاه أم لا ، لن يصبح PowerShell متوقّعًا أبدًا بحيث يمكنني تقليل تغطية الاختبار بشكل كبير. بعبارة أخرى ، الطريقة التي أستخدم بها PowerShell ، لا أعتقد أن هناك الكثير من الاتجاه الصعودي الذي يمكن حتى من خلال إجراء التغييرات العاجلة المقترحة أعلاه.

(راجع للشغل ، شكرًا لك @ mklement0 على طرح هذا السؤال مباشرة. لقد كان هذا في مؤخرة ذهني لفترة من الوقت. من الجيد أن أرى الفرصة للجميع ليقولوا مقالهم.)

شكرا @ alx9r.

أعتقد أنه من المهم التمييز بين التعقيد _ الداخلي_ والتعقيد _ الخارج_:

  • _Intrinsic_ ينبع التعقيد من التعقيد المتأصل للمفاهيم التي يتم تنفيذها ، والتي في حالة PowerShell لها مصدران أساسيان: التعقيد الداخلي من تقديم نموذج جديد (خط الأنابيب القائم على الكائن) والزواج من عالمين متميزين (بناء جملة القشرة وبناء جملة لغة البرمجة ) ، والتعقيد _ الخارجي_ من التفاعل مع عوالم خارجية متعددة ومتباينة.

  • ينبع التعقيد الاستثنائي من التسريبات التجريدية وعدم الاتساق.

    • يجب إزالة هذا التعقيد.
    • إذا لم يكن هذا خيارًا بسبب مخاوف التوافق مع الإصدارات السابقة ، فيجب توثيق هذا التعقيد على أنه مشاكل معروفة.

    • يعد سلوك تحديد النطاق المتغير لوحدة البرنامج النصي (الذي تشير إليه في سياق $_ ) أكثر من مجرد نزوة: إنه السبب الجذري لمشكلة كبيرة ، وهو الرقم 4568 المذكور سابقًا.

    • تصدمني جميع المشكلات الأخرى التي ذكرتها على أنها تندرج في الفئة الخارجية (بدلاً من كونها نتيجة تصميم دقيق) ، لأنها تقدم جميعًا على أنها تناقضات ليس لها مبرر أو فائدة واضحة (موثقة):

      • يكون الأمر أكثر منطقية عند استخدام $null لتمرير وسيطات _ no_ بدلاً من الوسيطة الموضعية $null .
      • لماذا يتم تحويل [System.Management.Automation.Internal.AutomationNull]::Value إلى $null أثناء _ ربط المعلمة _ ، على الرغم من الاحتفاظ بالنوع في _direct متغير_إسناد_؟ راجع https://github.com/PowerShell/PowerShell/issues/9150#issuecomment -473743805
      • ما فائدة تحديد النطاق الديناميكي لـ break و continue ، عبر مكدس الاستدعاءات ، مع _ إنهاء هادئ_ إذا لم يتم العثور على حلقة متضمنة؟

في حين أن ثروة الميزات والانضمام إلى عوالم متباينة وحده يجعل من الصعب تذكر جميع التعقيدات الأساسية ، فإن التقليل من العوالم الخارجية لا يزال مهمًا.

إن الاضطرار إلى اختبار نهجك المقصود أولاً دون معرفة وثقة أنه سينجح - أو تعطل الأشياء بشكل غير متوقع بسبب السلوك المفاجئ - يعد عائقًا جادًا في الإنتاجية (والتمتع) (على الرغم من أن PowerShell يجعل من السهل جدًا اختبار السلوك بشكل تفاعلي ).

يتعلق الأمر بمفاهيم صلبة (لا تتعارض مع التوقعات البديهية) ، والتسمية الوصفية ، والتوثيق الجيد:

إذا كنت لا أعرف ذلك / لست متأكدًا مما إذا كنت أتذكر بشكل صحيح ، فأنا بحاجة إلى معرفة مكان البحث عنه ، وأعتقد أن _المشكلات المعروفة وحالات الحافة _ موثقة أيضًا (إما كجزء من مواضيع المساعدة العادية أو عبر الروابط هناك).

لذا ، حتى إذا قررنا أن "إزالة" التعقيد الخارجي ليس خيارًا ، فيمكننا على الأقل _ توثيقه بشكل منهجي _ والمناقشة هنا يمكن أن تكون بمثابة نقطة البداية لتجميع "معرض الأخطاء" (والذي قد يتضمن أيضًا حالات تعقيد _ داخلي_ لا مفر منه قد يكون مفاجئًا).

يمكننا على الأقل توثيقه بشكل منهجي - والمناقشة هنا يمكن أن تكون بمثابة نقطة انطلاق لتجميع "معرض الأخطاء"

قام رومان كوزمين بجمع مثل هذا المعرض منذ فترة ، هنا: https://github.com/nightroman/PowerShellTraps

شكرًا ، HumanEquivalentUnit - التي تبدو كمجموعة رائعة.

إلى جانب المشكلات التي تم جمعها في سلسلة الرسائل هذه ، يمكن أن تشكل أساسًا لمعرض يمثل جزءًا من الوثائق _ الرسمية_ ، مع زيادة كل إدخال ، حسب الاقتضاء:

  • منطق التصميم الذي يفسر سبب تبرير السلوك ، على الرغم من أنه قد يكون مفاجئًا ، بعد كل شيء (قد يؤدي تفسير مؤطر بشكل صحيح إلى اختفاء عنصر المفاجأة)

  • إقرارًا بالمشكلة ، موضحًا أن:

    • إما: لن يتم إصلاحه لصالح التوافق مع الإصدارات السابقة.
    • أو: أن يتم النظر في تغيير مستقبلي
    • أو: أن المشكلة قد تم إصلاحها بالفعل في PS _Core_

من الغريب أنه يجب أن يُسأل عما إذا كان الوقت قد حان لـ "PowerShell vZeroTechnicalDebt" _

بالضبط لهذا هناك أمر إصدار مطلوب.

إذا حدث شيء ما في إصدار جديد ، فإن الألم الوحيد الذي نشعر به هو أنه يتعين علينا دراسة ومعرفة الاختلافات الصغيرة عادة.

لكننا (أخيرًا) نحصل على منصة ، والتي تتحسن حقًا مع كل تكرار في جوهره. وأسهل بكثير في الصيانة.

لا ، ليس هناك سؤال مطلقًا عن إطلاق التصميمات والقرارات السيئة من خلال المعرفة والتكنولوجيا الجديدة.

أيضًا ، لإخراج الأحياء من حصان ميت ، لا يزال من الصعب للغاية كتابة دالة حسنة التصرف أو أمر cmdlet الذي يتعامل مع الاختلافات السحرية بين نظام الملفات الأصلي للمضيف وموفر نظام الملفات. من الصعب كتابة مثل هذه التعليمات البرمجية الدقيقة وغالبًا ما تكون خاطئة. إليك منشور على stackoverflow الذي أجبته منذ حوالي سبع أو ثماني سنوات ولا يزال صالحًا:

https://stackoverflow.com/questions/8505294/how-do-i-deal-with-paths-when-writing-a-powershell-cmdlet

المرجع: # ​​8495

هناك بعض قواعد أسبقية المشغل الغريبة التي تستحق المراجعات:

PS> 1, 2, 2 + 1, 4, 4 + 1
1
2
2
1
4
4
1

في معظم اللغات ، يتوقع المرء أن يكون هذا هو الناتج:

1
2
3
4
5

أحد الخيارات التي لها مزاياها وعيوبها هو علامة ميزة جديدة لتمكين كل السلوك "المثالي" بحيث يتم تمكينه. إذا كان لدينا بعض القياس عن بُعد الذي يشير إلى أن معظم الاستخدام قد انتقل إلى السلوك الجديد ، فيمكننا قلبه بحيث يتم إلغاء الاشتراك. قد يكون هذا مجرد حلم بعيد المنال لأنني لم أر أي حالة في العالم الحقيقي حيث نجح مثل هذا النموذج ...

في الواقع ، سيكون ذلك "لطيفًا" ، ولكن نظرًا لطبيعة بعض هذه التنقيحات في هذا الموضوع ... شاملة إلى حد ما ، فإنه من المحتمل أن يؤدي إلى توافق كامل للنصوص بين "عادي" و "تجريبي" ، وربما إلى عدة أجزاء ، اعتمادًا على العلامات التي قام الفرد بتمكينها.

هذا يعني أنه لا يمكننا الاعتماد حقًا على أي شيء يمثل ميزة تجريبية بهذه الطريقة ، ولا نكتب نصوصًا ووحدات نمطية تعتمد عليها ، ما لم نرفق تحذيرًا كبيرًا بصفحات المستندات ، أو يحتمل أن نمنع استيرادها ما لم يتم وضع علامات معينة تم تمكينها.

هذا _يمكن_ أن يكون قابلاً للتجنب ... إذا كان بإمكاننا ، حسب الرغبة ، تمكين وتعطيل ميزات تجريبية محددة على أساس نطاق كل وحدة نمطية. ولكن نظرًا لأن هذا يزيد الأمور تعقيدًا ، فأنا لست متأكدًا مما إذا كان هذا حلاً رائعًا أيضًا.

@ vexx32 فقط experimental والتي ستصبح في النهاية غير تجريبية. كنت أفكر في شيء مختلف (ربما يكون أكثر مثل Enable-PSFeature لأنه سيكون مدعومًا رسميًا (وبالتالي محميًا من كسر التغييرات على عكس الميزات التجريبية)). كنت أفكر أيضًا أنه سيكون علمًا واحدًا حيث يمكنك الاشتراك في هذه التغييرات الجديدة كمجموعة وليس بشكل فردي.

أوه ، في هذه الحالة ... نعم ، بالتأكيد. سيتيح لنا ذلك تجميع كل شيء بدقة تحت مظلة واحدة ، واستخدامه بالفعل. أفضل بكثير مما كنت أفكر فيه! 😄

إضافة @ jszabo98 إلى قائمة المشكلات التي تم تجميعها هنا ، بناءً على # 8512:

-and و -or بشكل غير متوقع لهما الأسبقية _same_ ، بينما في معظم اللغات (بما في ذلك C #) يكون لـ -and أسبقية أعلى من -or .

تعبير مثال يتعارض مع التوقعات:

PS> $true -or $true -and $false
False

بسبب الارتباط الأيسر و -and و -or لهما نفس الأسبقية ، تم تقييم ما سبق على أنه ($true -or $true) -and $false بدلاً من $true -or ($true -and $false) المتوقع

قد يكون هذا مجرد حلم بعيد المنال لأنني لم أر أي حالة في العالم الحقيقي حيث نجح مثل هذا النموذج ...

في الواقع ، لدينا بالفعل نموذج يعمل في جميع أنحاء العالم - LTS. يستخدم MSFT هذا لتطوير Windows 10. يستخدم هذا النموذج لتطوير توزيعات Unix.
بالنسبة لنا ، هذا يعني أنه يمكننا إصدار إصدارات LTS PowerShell Core كل عامين وتضمينها في إصدارات Windows 10 LTS وإصدار Unix LTS. (تتمثل إحدى المشكلات في مزامنة تواريخ إصدار Windows و Unix لإصدارات LTS. أعتقد أن MSFT يمكنها التفاوض مع شركات Unix الرئيسية.)
خلال هذين العامين ، نقوم بجمع التغييرات الطفيفة ، ونقل التغييرات الأكثر أهمية إلى الدورة التالية.
لكل إصدار LTS جديد ، يجب أن يحصل ScriptAnalyzer على مجموعة من القواعد الجديدة لتسهيل ترحيل البرنامج النصي.
باستخدام هذا النموذج ، سيتعين على المنتجات والبرامج النصية المهمة الانتقال من الإصدار السابق إلى الإصدار التالي بعد إجراء اختبار شامل وترحيل.

لقد استخدمت هذا الأسلوب عندما قمت بترحيل خطوة بخطوة (إصدارًا بإصدار) نظامًا قديمًا من إصدار PHP 4 إلى إصدار PHP التالي حتى وصلت إلى إصدار PHP 5.x المدعوم. في كل خطوة ، كان علي إجراء تغييرات صغيرة وسريعة نسبيًا ، وبعد ذلك استمر النظام في العمل لبعض الوقت حتى الخطوة التالية.

تحديث: يجب أن يكون متزامنًا مع إصدارات NET Core LTS. أتوقع أن يكون Net Core 3.1 هو LTS التالي و PowerShell Core 6.x يجب أن يكون في الإصدار.

بكل صراحه؟ هذا يبدو وكأنه فكرة _عظيمة_ حقًا لـ PowerShell Core. سيسمح لنا ذلك بإجراء تغييرات مفاجئة مثل هذه التي يمكن أن تساعدها حقًا على المضي قدمًا ، وليس إثقالها بمخاوف التوافق ، بينما _ أيضًا_ لا تثقل كاهلها بالعديد من التغييرات الفاصلة في الفترة الفاصلة بين إصدارات LTS.

المرجع: https://github.com/PowerShell/PowerShell/pull/8407#issuecomment -453221566

يفشل تأكيد Get-Variable -ValueOnly -Name myVar | Should -Be $var عندما يكون $var مصفوفة.

هذا لأن Get-Variable -ValueOnly لا يستخدم الحمل الزائد للتعداد لـ WriteObject() .

فيما يتعلق بالحصول على إصدارات متعددة من powerhell التي تحتوي على مجموعات ميزات مختلفة وتغييرات متقطعة: لدينا هذا بالفعل مع الإرث والجوهر. الذي يبدو سيئًا للوهلة الأولى ولكنه قد يوفر نموذجًا عمليًا للمستقبل. ابقى معي...

يتعين علينا تعيين جميع العمليات تقريبًا التي تستخدم بوويرشيل لاستدعاء النواة pwsh.exe قبل تشغيل البرامج النصية الفعلية لأن مهام Windows المجدولة و jenkins والعديد من البيئات ليست على دراية بوويرشيل الأساسية. نقوم بذلك لأننا نستخدم ميزات لا تتوفر إلا في إصدار PS معين.

في الحالات التي لا يمكننا فيها فرض استدعاء لـ core ، يتعين علينا أن نتحقق من كل برنامج نصي من إصدار PS الذي يعمل تحته ثم استدعاء نفسه باستخدام إصدار PS المناسب على النظام المضيف. مهما كانت الحيلة التي نستخدمها للحصول على الكود الصحيح للتشغيل في البيئة المناسبة ، فإننا غالبًا ما نمرر كل البيئة والمعلمات إلى نفس البرنامج النصي الذي كان قيد التشغيل بالفعل.

هذه هي فلسفة UNIX. اجعل الأداة تفعل شيئًا واحدًا وافعلها جيدًا. ثم اجمع بين الأدوات لإنشاء كل أكبر من مجموع أجزائه. هذا هو عالم البرمجة النصية حيث نجري مكالمات فرعية إلى المرافق الأخرى طوال الوقت ونتائج العملية. تاريخيا هذا هو البرمجة النصية. تتجه Powershell نحو اتفاقية غريبة من خلال محاولة الاحتفاظ بكل الكود الأصلي ولكن هذا مجرد اصطلاح - وليس شرطًا. يعمل PS مع الوصول إلى نظام التشغيل وجميع الأدوات المساعدة المتاحة تمامًا مثل البرامج النصية لـ unix shell.

سيكون هذا أسهل بكثير إذا تم تحديث امتداد الملف للنواة إلى .ps6 حتى يتمكن محرك powerhell من القيام بالعمل نيابةً عنا. يمكن أن تظل كل نسخة ثنائية من powerhell مستقلة عن الآخرين طالما أن كل استدعاء لأحدهم يمر بالبيئات ويعيد المخرجات والأخطاء والتحذيرات والاستثناءات إلى الآخر - وهو ما يتعين علينا القيام به يدويًا الآن بجهد كبير. ليس من الضروري وجود أعلام متوافقة مع الإصدارات السابقة في المحرك طالما أن المحرك يعرف الإصدار الذي سيتم تشغيله. يحدث تبديل السياق المتضمن بالفعل ، لذلك نحن بالفعل في أسوأ السيناريوهات.

سنضطر إلى استخدام الاختراقات الفظيعة في بوويرشيل إلى الأبد ما لم نمضي قدمًا ونكسر الأشياء بطريقة محددة جيدًا. التغييرات المتقطعة لن تجعل حياتنا أكثر صعوبة مما هي عليه بالفعل. بدلاً من ذلك ، إذا استخدمنا التحسين التدريجي المستمر وجعل المحرك يقوم بالرفع الثقيل لسياق التبديل ، فسيكون رمزنا (والحياة) أفضل.

@ jtmoree-kahalamgmt-com شكرًا على ملاحظاتك! لا تتردد في فتح قضايا جديدة لمشاركة تجربتك وتعليقاتك وطرح ميزات مفيدة جديدة.

سيكون هذا أسهل بكثير إذا تم تحديث امتداد الملف للنواة إلى .ps6 حتى يتمكن محرك powerhell من القيام بالعمل نيابةً عنا.

راجع https://github.com/PowerShell/PowerShell/issues/2013#issuecomment -247987977

وأنشأت https://github.com/PowerShell/PowerShell/issues/9138 بناءً على تعليقاتك.

Python 3 هو بالتأكيد عرض الرعب ، هل اشتعلت بالفعل حتى الآن؟ ما زلت أعمل 2.7 ، ولا أخطط للترقية في أي وقت قريبًا. لكنني لم أسمع الكثير عن بيرل 6 مؤخرًا أيضًا ...

أعتقد أن الدروس التي يجب تعلمها من Python هناك هي فصل التغييرات العاجلة على اللغة من تغيير الإصدار إلى المحرك. افتراضيًا ، لا يزال بإمكان محرك PS 7 تشغيل ملفات البرامج النصية السابقة (.PS1) في وضع تغييرات لا يمكن كسرها ، بينما إذا تم وضع علامة على البرنامج النصي على أنه 7 مدرك (على سبيل المثال بامتداد PS7) ، فيمكنهم إعلان أنه تم تحديثه _ و_ ذلك تتطلب PS 7 على الأقل للتشغيل. اتمنى ان يكون هذا منطقي

أعتقد أن وصف Python 3 بأنه عرض رعب مثير للغاية. إذا نظرت إلى حزم PyPi التي تم تنزيلها ، وحصلت على البيانات الوصفية للحزمة الفردية حول تنزيلات v2 مقابل v3 ، أرى أن الإصدار 3 قد كسر الآن نسبة اختراق 33٪ لجميع الحزم العليا تقريبًا ، وللمكتبات الأحدث مثل مكتبة طلبات Ken Reitz ، تقسيم 50/50 تقريبًا: بالأمس كان هناك 685 ألف تنزيل للإصدار 3 مقابل 875 ألفًا من الإصدار 2.0.

كان الشيء الرئيسي وراء عودة Python 3 لفترة طويلة هو دعم المجتمع العلمي للباندا و pysci. ولكن ، في أحدث الإحصائيات ، يفضل المجتمع العلمي الآن Python 3 على Python 2: https://pypistats.org/packages/pandas 231k v3 التنزيلات ، مقابل 175k v2 التنزيلات.

كما قال الدكتور دبليو إدواردز دمينغ الشهير ، "بالله نثق ، وكل الآخرين يجلبون البيانات!" ربما يمكنك كتابة نص برمجي PowerShell لتحليل مجموعة بيانات PyPi وإخباري بمدى استخدام Python 3 المروع للبيانات: https://packaging.python.org/guides/analyzing-pypi-package-downloads/

سأكون سعيدًا (بهذا الترتيب الدقيق):

  1. أسهل في استخدام نظام الوحدة الذي ينتج تتبعات جيدة للمكدس.

    • على سبيل المثال ، يسمح ملف psm1 بوصف القواعد التعسفية لكيفية تحميل الوظائف ، ولكن هذا يسبب تتبعات مكدس مشفرة حيث يتم دمج جميع الوظائف في ملف psm1 منطقيًا. هذا يعني أن أرقام الأسطر الموجودة على آثار المكدس مفيدة مثل إبريق الشاي بالشوكولاتة.
  2. استبدل تنسيق سلسلة كائن خطأ PowerShell الافتراضي الذي يبتلع 99 ٪ من فائدة البرمجة في بنية von Neumann القائمة على المكدس.

    • C # أكثر أو أقل يحصل على هذا الحق. PowerShell ذكي جدًا بمقدار النصف.
  3. إصلاح إعادة التوجيه الفارغة بحيث تكون الطرق الثلاث المختلفة لإعادة توجيه تدفقات الإخراج إلى الجهاز الخالي متكافئة في الأداء.

  4. إصلاح النطاق الديناميكي :

function a($f) {& $f}
function main() {
    $f = {write-host 'success'}
    a {& $f} # stack-overflow
    a {& $f}.getnewclosure() # okay
}
[void] (main)
  1. إصلاح الالتقاط المتغير :
set-strictmode -version 'latest'
$erroractionpreference = 'stop'

function main() {
    $a = 'foo'
    $f = {
        $g = {$a}.getnewclosure()
        & $g # "variable '$a' cannot be retrieved because it has not been set."
    }.getnewclosure()
    & $f
}

main
  1. يتراكم الناتج return لا يفعل نفس الشيء مثل اللغات الأخرى؛ اصلحه.

  2. لا يحتوي PowerShell على سكر نحوي للتخلص من الموارد الخارجية للكائنات

  3. أعد كتابة PowerShellGet. مريع. وظائف مع مئات الأسطر من التعليمات البرمجية ، والاستثناءات المبتلعة ، وعدم وجود تغطية اختبار.

  4. تخلص من كيفية عمل وحدة التخزين المؤقت.

    • ذاكرة التخزين المؤقت ليست آمنة لمؤشر الترابط. WTF؟
    • المفهوم الكامل للتخزين المؤقت لوحدة ما لأغراض التحليل هو kludge / hack. أدرك أن هناك دعمًا كبيرًا داخل Microsoft لهذه الميزة لأن PowerShell بطيء للغاية ، لكن انظر اقتراحي التالي لإصلاح حقيقي.
    • الطريقة الوحيدة لمسح AnalysisCache الخاص بك هي إعادة تشغيل PowerShell.exe
    • يؤدي التخزين المؤقت للوحدات لأغراض التحليل إلى ربط التحليل بإحكام بحالة وقت تشغيل الوحدات.
  5. توفير "وحدات مجمعة" مشابهة لكيفية تجميع ملفات Py لملفات pyc لتحسين الأداء.

  6. أضف $none حرفية

    • ضع في اعتبارك استبدال $null بـ $none في العديد من الأماكن
    • أعد النظر في كيفية عمل ParameterSetName ، واسمح بتمرير قيمة خاصة $none إلى المعلمات ، حتى لا أحتاج إلى كتابة عبارات تبديل مجنونة لاستدعاء الكود 5 طرق مختلفة. يقوم COM و C # dynamic بعمل هذا بشكل صحيح - PowerShell يجعل هذه كارثة. من الأمثلة على ذلك كيف يتعين علي تعيين تكوين نشر لتقارير SSRS ديناميكيًا في الوحدة النمطية ReportingServicesTools استنادًا إلى نوع حدوث الاشتراك. أفضل فقط تمرير مجموعة من الخصائص والحصول على الطريقة للتعامل داخليًا مع التعقيد ، بدلاً من فرض التعقيد الخارجي على المستخدمين النهائيين. ParameterSetName مفيد فقط كمفهوم كقالب ، وليس جيدًا للبرمجة مقابل. إنه يشوش تعدد الأشكال المخصص مع التحسس.

jzabroski فيما يتعلق بتنسيق ErrorRecord ، هناك مشكلة منفصلة تستخدم لمناقشة ذلك: https://github.com/PowerShell/PowerShell/issues/3647 ، نظرًا لأن التنسيق لا يعتبر تغييرًا جذريًا ، يمكننا إجراء تحسينات هناك.

من المحتمل أن تكون بعض طلباتك الأخرى مضافة ولا تنكسر ، لذا يجب أن تكون هذه مشكلات منفصلة. تناقش هذه المشكلة المحددة طلبات تغيير التغييرات إذا أتيحت لنا الفرصة ويمكن أن نبرر القيام بإصدار رئيسي جديد من PS.

jzabroski فيما يتعلق بتنسيق ErrorRecord ، هناك مشكلة منفصلة تُستخدم لمناقشة ما يلي: # 3647 ، نظرًا لأن التنسيق لا يعتبر تغييرًا مفاجئًا ، يمكننا إجراء تحسينات هناك.

_لماذا لا يعد تغييرًا جذريًا؟ لأن المطورين يجب ألا يتطابقوا مع السلاسل في رسائل الخطأ في المقام الأول؟ أعتقد أن هذا صحيح. لكنها ستظل تحطم المستهلكين في المصب.

من المحتمل أن تكون بعض طلباتك الأخرى مضافة ولا تنكسر ، لذا يجب أن تكون هذه مشكلات منفصلة.

أي منها في رأيك يحتمل أن تكون مضافة؟ يمكنني إنشاء قضايا لهم حتى لا نخرج هذه المناقشة عن مسارها ، لكنني وضعت هذه القائمة بعناية هذا الصباح. أنا أكره PowerShell مع غضب وشغف من الرعد المتداول والبرق المتفجر. بوويرشيل كرة بولينج بسكين جزار. لقد حدثت أكثر 5 لحظات محرجة لدي كمهندس أثناء استخدام PowerShell. لن أستعيد ذلك الوقت أبدًا.

لقد قمت بتحديث اقتراحاتي لتوضيح سبب تعطل هذه الاقتراحات (والرائعة) للتغيير.

يتراكم الناتج عودة لا تفعل نفس الشيء مثل اللغات الأخرى ؛ اصلحه.

يتصرف return بالشكل الذي تتوقعه ضمن طريقة class . تعتبر طريقة "تراكم الإخراج" في وظيفة PS عادية / متقدمة نموذجية جدًا لبيئات البرمجة النصية للصدفة مثل Korn shell و Bash. أي نسخ عدة أوامر من وحدة التحكم ووضعها في وظيفة. عندما تستدعي هذه الوظيفة ، فإنها تخرج من كل أمر تمامًا كما فعلت عند تنفيذ هذه الأوامر من وحدة التحكم.

مأخذي الأساسي مع PowerShell هو أنه في حالة الوظيفة العادية / المتقدمة ، يجب ألا يأخذ return الحجج مطلقًا. لأن شيئًا مثل:

return $foo

تم تنفيذه حقًا على النحو التالي:

$foo
return

هذا يعطي الناس إحساسًا بأنهم يستطيعون التحكم في الإخراج باستخدام الإرجاع ولا يمكنهم ذلك.

يتصرف return بالشكل الذي تتوقعه ضمن طريقة class . تعتبر طريقة "تراكم الإخراج" في وظيفة PS عادية / متقدمة نموذجية جدًا لبيئات البرمجة النصية للصدفة مثل Korn shell و Bash.

أسمع الناس يقولون هذا ، بما في ذلك BrucePay (انظر التوكيد الخاص بي أدناه ، نقلاً عنه) ، لكن الخلاصة هي:

فقط في PowerShell لدينا هذا "العائد لا يعود" غير المنطقي ويتراكم الناتج. هذا تسرب للذاكرة الممجدة ، ويجب أن تفكر في الأمر على هذا النحو.

لأكون صادقًا ، في كل مكان في PowerShell In Action ، أبحث عن عبارة "مشاكل" ، يمكنني إضافة شيء ما إلى قائمة vZeroTechnicalDebt. إليكم ما يكتبه بروس عن بيان الإرجاع:

7.3 إرجاع القيم من الوظائف
حان الوقت الآن للتحدث عن القيم المرتجعة من الوظائف. كنا نفعل هذا طوال الوقت ، ولكن هناك شيء نحتاج إلى تسليط الضوء عليه. نظرًا لأن PowerShell عبارة عن غلاف ، فإنه لا يُرجع النتائج — إنه يكتب الإخراج أو يرسل الكائنات. كما رأيت ، نتيجة أي تعبير أو خط أنابيب هو إرسال كائن النتيجة إلى المتصل. في سطر الأوامر ، إذا كتبت ثلاثة تعبيرات مفصولة بفواصل منقوطة ، فسيتم إخراج نتائج العبارات الثلاثة:
[...]
في الطريقة التقليدية ، عليك تهيئة متغير نتيجة ، $result ، للاحتفاظ بالمصفوفة التي يتم إنتاجها ، إضافة كل عنصر إلى المصفوفة ، ثم إصدار المصفوفة:

PS (16) > function tradnum
> {
> $result = @()
> $i=1
> while ($i -le 10)
> {
> $result += $i
> $i++
> }
> $result
> }

هذا الرمز أكثر تعقيدًا بشكل ملحوظ: عليك إدارة متغيرين في الوظيفة الآن بدلاً من واحد. إذا كنت تكتب بلغة لا تقوم تلقائيًا بتوسيع حجم المصفوفة ، فسيكون الأمر أكثر تعقيدًا ، حيث سيتعين عليك إضافة رمز لتغيير حجم المصفوفة يدويًا. وعلى الرغم من أن PowerShell سيغير حجم المصفوفة تلقائيًا ، إلا أنه ليس فعالًا مقارنة بالتقاط الإخراج المتدفق. الهدف هو جعلك تفكر في كيفية استخدام التسهيلات التي يقدمها PowerShell لتحسينها
كودك. إذا وجدت نفسك تكتب كودًا ينشئ مصفوفات بشكل صريح ، ففكر في النظر إليه لمعرفة ما إذا كان يمكن إعادة كتابته للاستفادة من البث بدلاً من ذلك.

أعتقد أن الدافع وراء هذه الميزة لطيف ، ولكن هناك طرقًا أنظف وأسهل في القراءة لتحقيق نفس الهدف: الترويج الضمني من كائن واحد إلى مجموعة من الكائنات. علاوة على ذلك ، لدى PowerShell بالفعل طريقة بسيطة لإرجاع المخرجات لإعادة التوجيه: Write-Output .

في Bash ، يخرج العائد من دالة ، نقطة.

هاه؟ تجمع Bash المخرجات بنفس الطريقة:

hillr@Keith-Dell8500:~$ function foo() {
> echo "Hello"
> ls ~
> date
> return
> echo "World"
> }
hillr@Keith-Dell8500:~$ foo
Hello
bar.ps1  date.txt   test.ps1
baz.ps1  dotnet    powershell-preview_6.2.0-rc.1-1.ubuntu.16.04_amd64.deb
Tue Mar 26 16:06:18 DST 2019

تمامًا مثل PowerShell ، لا يزال Bash ينتج كل شيء بدءًا من كل أمر حتى بيان return .

آه ، أعتقد أنك تشير إلى ما تم إرجاعه بـ $? . نعم ، هذا فرق. أعتقد أن هذه القيم يجب أن تكون int في Bash للإشارة إلى النجاح / الفشل. في PS ، يشير $? إلى النجاح / الفشل كأداة منطقية تستند إلى الأخطاء الناتجة عن الوظيفة. من الناحية العملية ، لا أعتقد أن $? لا يستخدم كثيرًا. أستخدم معالجة الاستثناء عبر try/catch/finally بدلاً من ذلك.

نعم. return له غرض واحد فقط بهذه اللغات. في PowerShell ، يتم مزجه مع الإخراج. يعتبر خلط قيم الإرجاع وتدفقات الإخراج فكرة سيئة. يمكن أن يؤدي أيضًا إلى مشاكل أداء تشبه تسرب الذاكرة. ما تريده حقًا هو الإجراءات المشتركة أو "العائد" أو المولدات وبناة المولدات والماسحات الضوئية (كما في Icon). والسبب هو أن استهلاك المدخلات كسول وأن الفشل يوقف الحساب بينما يسمح بالتخلص من جزء الحساب الذي تم إنشاؤه حتى الآن.

يمكنك التفكير في "إعادة توجيه الإخراج" ككائنين بالفعل: المعالج و ProcessorContext.

تحرير: فهمت لماذا دحضت وجهة نظري الأصلية. كنت تعتقد أنني كنت أقول أنه من السيئ أن تكون قادرًا على تحقيق الناتج. أنا أقول بدلاً من ذلك أنه من السيئ إعادة الإخراج بالطريقة التي يقوم بها PowerShell.

أستخدم معالجة الاستثناء عبر try/catch/finally بدلاً من ذلك.

هذا كثير من الكتابة ، ولا يعبر بوضوح عن النية في جميع الحالات.

حسنًا ، يعتمد PowerShell على .NET وهو عبارة عن تجميع للقمامة ، لذلك لا ينبغي أن يعاني من "تسرب" الذاكرة. هذا لا يعني أنه لا يمكنك امتلاك ذاكرة تخزين بالرغم من ذلك. لذلك عليك أن تكون حريصًا بعض الشيء عند التعامل مع المخرجات / المجموعات الكبيرة التي يتم تعيينها إلى متغير أو وضعها في علامة التجزئة من نوع ما.

أعتقد أن بيان PowerShell return يجب أن يكون له غرض واحد فقط وهو العودة مبكرًا - لا شيء آخر. عندما يقوم شخص ما بعمل return 42 فلن يكون لذلك تأثير على $? إنه مجرد إخراج عنصر آخر (يتم إنتاجه) لتدفق الإخراج.

كما ذكرت من قبل ، تتم إدارة $? بواسطة PowerShell وليس له علاقة بما تنتجه / ترجع الدالة. $? بناءً على الأخطاء المتولدة (أو عدم وجودها). هذا يعني أنه عند تنفيذ $res = foo - سيحتوي $ res على كل كائن ناتج بواسطة التابع foo. إذا كنت تريد معرفة ما إذا كانت الوظيفة "فشلت" ، يمكنك فحص $? في كل أمر تقوم بتنفيذه أو يمكنك لف مجموعة من الأوامر في كتلة try/catch . أجد السابق أقل كتابة (في البرامج النصية).

سماع الناس يقولون هذا ، بما في ذلك BrucePay (انظر التوكيد ، أدناه ، نقلاً عنه) ، لكن الخلاصة هي:
في Korn Shell ، يخرج الإرجاع دالة ، نقطة.
في Bash ، يخرج العائد من دالة ، نقطة.

في PowerShell ، يخرج الإرجاع من وظيفة أيضًا:

PS C:\> function test { "hello"; return "!"; "world"}
PS C:\> test
hello
!

يعتبر خلط قيم الإرجاع وتدفقات الإخراج فكرة سيئة. يمكن أن يؤدي أيضًا إلى مشاكل أداء تشبه تسرب الذاكرة

لا يوجد خلط لأنه لا يوجد فرق بين دفق الإخراج وقيمة الإرجاع في PowerShell. أنت تتحدث كما لو أن الوظيفة تكتب السلاسل إلى stdout وترجع علامة تعجب بشكل منفصل إلى المتصل ، لكنها لا تفعل ذلك. يبدو أن الإشارة إلى write-output هي نفس الخطأ ؛ كل ما يلي: write-output 'x' ، 'x' ، return 'x' أرسل شيئًا ما أسفل مسار الإخراج نفسه ، إلى خط الأنابيب. لا توجد قيمة إرجاع منفصلة.

ما تريده حقًا هو الإجراءات المشتركة أو "العائد" أو المولدات وبناة المولدات والماسحات الضوئية (كما في Icon). تي

هذا يعني أنك إذا كتبت أمرًا في سطر الأوامر ، ثم وضعته في نص أو وظيفة ، فسوف يتصرف بشكل مختلف:

PS C:\> robocopy /whatever
PS C:\> "robocopy /whatever" | set-content test.ps1; .\test.ps1
PS C:\> function test { robocopy /whatever }

أحب رؤية نفس الناتج في جميع الحالات الثلاث ، ولم يتم ابتلاع المخرجات في حالتين لأنني لم أكن yield return بدون سبب. الطريقة التي يعمل بها PowerShell متسقة وملائمة للقشرة وكتابة نصوص برمجية shell / batch - أخذ شيء كتبته في سطر الأوامر ووضعه في مكان يمكنك تسميته مرارًا وتكرارًا. لا ينبغي أن يؤدي القيام بذلك إلى تغيير سلوك الكود تمامًا.

والسبب هو أن استهلاك المدخلات كسول وأن الفشل يوقف الحساب بينما يسمح بالتخلص من جزء الحساب الذي تم إنشاؤه حتى الآن.

يتم التحكم في خط أنابيب PowerShell من خلال وقت التشغيل ، إذا فهمت ما تقوله ، فيمكنه بالفعل القيام بذلك:

PS D:\> 1..1mb |foreach { write-verbose -Verbose "incoming number: $_"; $_ } |select -first 3
VERBOSE: incoming number: 1
1
VERBOSE: incoming number: 2
2
VERBOSE: incoming number: 3
3

select خط الأنابيب بمجرد أن يحتوي على ثلاثة أشياء لم يتم إدخال بقية المليون في foreach . المعلومات التي تتحرك أسفل خط الأنابيب هي نموذج "دفع" ، ولكن يتم التحكم فيها بواسطة محرك PowerShell.

على الرغم من كونها قذيفة ، فليس من الواضح ما الذي يعنيه "فشل الإدخال في تعليق الحساب" إذا كان الإدخال قادمًا من أمر أصلي أو شيء خارج PS cmdlet.

توفير "وحدات مجمعة" مشابهة لكيفية تجميع ملفات Py لملفات pyc لتحسين الأداء.

أعتقد أن الحل المقصود لمزيد من الأداء هو كتابة وحدات في C #. يتم تجميع كود PowerShell JIT ، في بعض المواقف ، لكن أعضاء فريق PS قالوا قبل أن ليس لديهم أي خطة لفضح ذلك للمستخدمين النهائيين للتخصيص ، على سبيل المثال ، تحدث PS Conf Asia من IIRC

إصلاح إعادة التوجيه الفارغة بحيث تكون الطرق الثلاث المختلفة لإعادة توجيه تدفقات الإخراج إلى الجهاز الخالي متكافئة في الأداء.

مرغوب فيه ، لكنه يبدو غير مرجح ؛ $null = 4 هو ربط بسيط المتغير، 4 | out-null يحتاج النفقات العامة من بدء خط أنابيب والقيام قرار القيادة - ما إذا كان شخص ما قد قدم عمدا out-null وكيل-المجمع الذي أضاف تسجيل الشفرة؟ هل هذا الدين الفني ، أن طلب خط أنابيب و cmdlet للتشغيل أبطأ من التعبير؟

إصلاح النطاق الديناميكي:

إذا كنت تقصد "عدم استخدام النطاق الديناميكي" ، فقد كان اختيارًا متعمدًا ، على سبيل المثال ، يقول Bruce Payette هنا "النطاق الديناميكي ، لم يتم استخدام هذا تقريبًا ؛ من قبل ، مثل 30 عامًا مضت ، كان LISP يتمتع بنطاق ديناميكي ، ولكنه نادر جدًا جدًا الآن. السبب في أننا نستخدمها هو: هذا ما تستخدمه القذائف. تستخدم القذائف ما يعادل النطاق الديناميكي ، حتى Bash ، وتستخدم أصداف Unix ما يعادل النطاق الديناميكي ، حيث المتغيرات من سياق المتصل - في حالتهم يتم نسخ المتغيرات من سياق المتصل إلى السياق الفرعي. [..] مع تعديل واحد ، عادةً في النطاق الديناميكي ، تبحث عن سلسلة الاستدعاء وتضبط المتغير حيث يوجد ، لا نفعل ذلك ، نحن نضبط المتغير في النطاق الحالي طوال الوقت ، ومرة ​​أخرى يحاكي سلوك الأصداف ".

قد يكون هذا مزعجًا ، لكن هل هذا "الدين الفني" للقذيفة ، وسيكون "صفرًا من الديون الفنية" إذا تم تغييره؟

حسنًا ، يعتمد PowerShell على .NET وهو عبارة عن تجميع للقمامة ، لذلك لا ينبغي أن يعاني من "تسرب" الذاكرة. هذا لا يعني أنه لا يمكنك امتلاك ذاكرة تخزين بالرغم من ذلك. لذلك عليك أن تكون حريصًا بعض الشيء عند التعامل مع المخرجات / المجموعات الكبيرة التي يتم تعيينها إلى متغير أو وضعها في علامة التجزئة من نوع ما.

كان لدي مسؤول نظام ، وهو ليس مهندسًا ، يكتب بعض المنطق لمحاولة جدولة البيانات الوصفية على جميع الملفات على مشاركة ملف 8 تيرابايت. لم ينته ذلك بشكل جيد: لقد استهلك الكثير من الذاكرة ، وربط النظام أيضًا بوحدة معالجة مركزية 100٪ ... لم نتمكن حتى من تسجيل الدخول إلى المربع بعد بدء البرنامج النصي ، والحل الوحيد _ في الإنتاج_ لحفظ الخادم كان من الصعب إعادة تشغيله.

من واقع خبرتي ، يجعل PowerShell من السهل كتابة مثل هذه القمامة. يمكنك أن تفعل مع ملاحظاتي ونقدها كيفما تشاء. لن يغير ذلك حقيقة أن PowerShell يجعل من السهل كتابة نصوص يمكن أن تعطل آلات الإنتاج بشكل فعال.

jzabroski هل يمكنك مشاركة أي تفاصيل عن البرنامج النصي؟

يحاول أفراد Powershell تشجيع تدفق خط الأنابيب ( get-childitem | foreach-object {} ) بدلاً من التحميل المسبق لمجموعة بيانات ( $files = get-childitem; $files | foreach-object ) عمدًا لتقليل استخدام الذاكرة. هل فعلت ذلك التحميل مقدمًا؟

هل كان هناك استخدام Group-Object لتجميع الملفات المماثلة؟ كانت هناك تحسينات في أداء Group-Object مؤخرًا والتي من شأنها تقليل استخدام وحدة المعالجة المركزية ، إن لم يكن استخدام الذاكرة.

يعد PowerShell أحادي النواة بشكل افتراضي ، هل كان هناك رمز وظائف / مساحات تشغيل هناك ، هل كان خادمًا أساسيًا واحدًا؟ يحتوي PS 6.1 على Start-ThreadJob الذي يسمح بمهام متعددة مع طريقة أقل من الحمل

من واقع خبرتي ، يجعل PowerShell من السهل كتابة مثل هذه القمامة

كل الدروس والكتب التي تطلب منك كتابة $files = @(); $files += $f قد كلفت العالم ثروة صغيرة في دورات وحدة المعالجة المركزية والذاكرة. هذا نمط بطيء ومكلف من حيث المعالج والذاكرة وشائع بشكل مزعج. أشعر بالفضول إذا كان هذا النمط موجودًا في البرنامج النصي على الإطلاق؟ (وإذا كان هناك أي طريقة يمكننا من خلالها حظره دون كسر التوافق مع الإصدارات السابقة ، أو جعل + = غير صالح على المصفوفات في تغييرات التكسير المستقبلية؟).

لكن هناك مقايضة هنا. Get-ChildItem -Recurse هو 22 حرفًا ويستهلك 800 + ميجابايت من ذاكرة الوصول العشوائي على محرك الأقراص C فقط ، أما C # للقيام بذلك دون استخدام الكثير من الذاكرة فهو أكثر من 50 سطرًا ولا يحصل على بيانات وصفية للملف على الإطلاق أكثر مثل 80 ميغا بايت. هذه ليست ذاكرة PS تسريبًا ، بل يستخدمها PS لتوفير راحة المستخدم.

هل هناك أي لغة لا تضطر فيها إلى الاهتمام بتفاصيل كيفية عملها ، ويمكنها كتابة تعليمات برمجية مفيدة ، ولا يمكنك كتابة تعليمات برمجية سيئة ، وليس عليك أن تكون مبرمجًا ماهرًا؟ (وما هي أيضًا صدفة؟)

هل كان أي من التغييرات التي اقترحتها سابقًا قد نجح في جعل البرنامج النصي يعمل؟

يمكنك كتابة نص برمجي Bash لقائمة الملفات ، وإنشاء عملية لكل واحد ، حتى ينتهي الخادم الخاص بك ولا يمكنك حتى SSH فيه. يمكنك كتابة برنامج نصي بلغة Python يحمل شجرة الملف os.walk() ويستدعي os.stat() لكل ملف ويستخدم ذاكرة أقل وينتهي بشكل أسرع - ولكنه يأخذ 10 أسطر بدلاً من 1 ولا يزال عليك الاهتمام به نظام التشغيل ويهتم بتفاصيل الكود (وما زال ليس قذيفة ، ولن يعمل مع مزودي PS).

أود أن يكون لدى PS المزيد من "نقاط النجاح" وتقليل مخاطر الرحلة. قائمة اسم الملف السريع هي واحدة من تلك التي أرى الكثير من الاستخدام لها. إن تغييرها جذريًا لتصبح لغة مختلفة تمامًا ، وإعاقة المناطق التي تعمل بها بشكل جيد ، لن يفعل ذلك.

أنت تريد Python ، لغة Python موجودة ، إنها لغة جميلة ، لا تتعثر من خلال محاولة التوافق في عالمين مختلفين والاستمرار في البحث عن دلالات الدالة وإرجاع الدلالات لقذيفة عمرها ثلاثين عامًا من نظام تشغيل مختلف (لماذا ، Microsoft) ، أو من خلال التزام Microsoft للتوافق مع الإصدارات السابقة (والاستحواذ على .Net) ، لذا يجب تفادي كل هذه الأسئلة ، بدلاً من مواجهتها.

أود أن يكون لدى PS المزيد من "نقاط النجاح" وتقليل مخاطر الرحلة.

إذا كان بإمكاني إضافة عشرين إبهامًا لذلك وحده ، فسأفعل. هذا هو بالضبط النمط والنهج الذي يجب على PowerShell اتباعه.

For-EachObject هي وظيفة PowerShell لأخذ مجموعات PowerShell وتحويلها إلى تتبعات مكدس غير قابلة للقراءة.

اليوم ، أخذت نصًا مكتوبًا بواسطة Amazon لإدراج أقراص EC2 Windows: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-volumes.html#windows -list-disks

خمين ما؟ لم يكن لدي إعداد Initialize-AWSDefaults على هذا الكمبيوتر ، وبما أن مؤلف البرنامج النصي استخدم ForEach-Object ، بدا تتبع المكدس الخاص بي مثل هذا _garbage_:

PS C:\Windows\system32> D:\Installs\PowerShell\List-EC2Disks.ps1
Could not access the AWS API, therefore, VolumeId is not available. 
Verify that you provided your access keys.
ForEach-Object : You cannot call a method on a null-valued expression.
At D:\Installs\PowerShell\List-EC2Disks.ps1:39 char:12
+ Get-disk | ForEach-Object {
+            ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [ForEach-Object], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull,Microsoft.PowerShell.Commands.ForEachObjectCommand

يحدث هذا _ في كل مرة يستخدم فيها الأشخاص تعبيرات ForEach-Object في التعليمات البرمجية الخاصة بهم. آثار المكدس _ دائمًا رهيبة_. إعادة كتابة هذا مؤلم. لحسن الحظ ، إنه مجرد برنامج نصي أقوم بنسخه ولصقه في ملف عشوائي وحفظه وتشغيله. إذا كانت هناك مشكلة في وحدة كبيرة ، يجب أن أحصل على الكود المصدري للوحدة ، وأعيد كتابة النص ، وأتمنى أن أعود إلى الله في إعادة بناءه ، لم أقم بتقسيم أي شيء عبر الوحدة عن طريق تحويل تعبير ForEach-Object وأمل يمكنني معرفة مكان الخطأ الحقيقي حتى أتمكن من القيام بعملي. والآن لدي بعض الكود المخصص الذي قمت بإنشائه من بعض المستودعات الرئيسية ، فقط لمعرفة سبب تلقيي بعض الخطأ لأن PowerShell's Write-Error رائع مقارنة بـ C # المصطلح البسيط throw new Exception("message", ex) .

إعادة كتابة هذا لاستخدام for ($var in $list) ، مع تجميع النتائج في متغير $results ، يظهر لي الخطأ التالي:

PS C:\Windows\system32> D:\Installs\PowerShell\List-EC2Disks.ps1
Could not access the AWS API, therefore, VolumeId is not available. 
Verify that you provided your access keys.
You cannot call a method on a null-valued expression.
At D:\Installs\PowerShell\List-EC2Disks.ps1:58 char:26
+ ... lDevice = If ($VirtualDeviceMap.ContainsKey($BlockDeviceName)) { $Vir ...
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

أوه ، وبالمناسبة ، في كل مرة يجب أن أفعل ذلك ، لا أتذكر قواعد PowerShell الغبية لإضافة عناصر إلى القوائم ، لذلك يجب أن أذهب إلى Google https://www.google.com/search؟q=powershell+append + إلى + قائمة وقراءة منشور مدونة عن شخص ما يشرح كيفية عمليات قائمة PowerShell غير البديهية.

إذا كنت لا تعرف لغة C # أو لغة تفعل ذلك جيدًا ، فمن السهل القول بأن هذا السلوك لا بأس به. ومع ذلك ، تعالج C # هذه المشكلة بذكاء عن طريق التفاف الاستثناء في AggregateException ، بحيث تحصل على كل من الاستثناء الداخلي والخارجي. بوويرشيل؟ هاهاهاها. نعم ، سيكون ذلك مفيدًا جدًا.

jzabroski هل يمكنك مشاركة أي تفاصيل عن البرنامج النصي؟

للأسف (_ ولحسن الحظ _) ، لا أتذكر ذلك. لقد كانت مشاركة في الملفات ، لذلك كان من شبه المؤكد أنه كان عبارة عن مركز أو مركزين على الأكثر. إذا كان هناك مركزان ، فمن المحتمل أن يكون Windows Defender مأخوذًا من وحدة المعالجة المركزية المتبقية.

تحرير: تم العثور عليه في دردشة Teams.

$big32 = Get-ChildItem D:\Data\Website\Data -recurse | Sort-Object length -descending | select-object -first 32 | measure-object -property length –sum

كمكافأة إضافية ، لقد تحدثت للتو إلى الشخص الذي قام بتشغيل هذا الأمر (وشعرت بالسوء بشكل لا يصدق) ، وقال إن حالة الاستخدام "كانت الحصول على أكبر 32 ملفًا لمتطلبات تحجيم مجموعة النسخ المتماثل الأولي لـ DFS".

لا يوجد خلط لأنه لا يوجد فرق بين دفق الإخراج وقيمة الإرجاع في PowerShell.

ما زلت أرى الناس يستخدمون هذا بشكل صحيح في المحاولة الأولى. مرة أخرى ، ليس هذا ما يفعله باش أو أي قذيفة أخرى. في حين أنها كانت تجربة مثيرة للاهتمام لتوحيد المفهومين ، إلا أنها كانت كارثة كاملة ومطلقة من وجهة نظر القراءة. لا يساعد أن Write-Output تم كسره في PowerShell v6 لمدة 16 شهرًا.

jzabroski من مخرجاتك For-EachObject يبدو أنك لا تستخدم Powershell Core (هذا هو ما تم تخصيص هذا المستودع له) هل يمكنك من فضلك تجربة Powershell core ومعرفة ما إذا كان يمكنك إعادة إنتاجه. تأكد من استخدام أحدث إصدار. ضع في اعتبارك أن وظائف Windows المحددة (مثل Get-Disk) ليست جزءًا من Powershell Core ، فستحتاج إلى أخذ ذلك في الاعتبار أثناء إجراء الاختبارات.

ما زلت أرى الناس يستخدمون هذا بشكل صحيح في المحاولة الأولى. مرة أخرى ، ليس هذا ما يفعله باش أو أي قذيفة أخرى.

$ test () { ls /tmp; ls /etc/pm; return 5; ls /v*; } ; x=$(test)
$ echo "$x"
tmux-1000
sleep.d
$ echo $?
0

في آن معا إخراج قيادتين منفصلتين تتراكم في وظيفة باش، وباش عودة لا يعمل وظائف العودة في C #. ما هو بالتحديد "ليس ما يفعله باش"؟

أنت لا تلتقط القيمة المعادة بشكل صحيح لمثال bash. العودة تضيع لأن $؟ هو دائما الأمر الأخير. في حالتك "صدى".

$ test () { ls /tmp; ls /etc/pm; return 5; ls /v*; } ; x=$(test)
$ echo $?
5
$ echo $x
tmux-1000
sleep.d

يقوم POWERSHELL بهذا بشكل مختلف

> function test() { ls; return 5 ; ls } ; $x=test
> echo $?
True
> echo $x
    Directory: c:\foo\bar

Mode                LastWriteTime         Length Name
----                -------------         ------ ----

المزيد من شذوذ PowerShell:

يضيف Chocolatey RefreshEnv.cmd وهو نداء من الله. لماذا لا يتم شحن هذا فقط مع PowerShell؟ لماذا أحتاج إلى إعادة تشغيل Shell أو تنزيل بعض البرامج النصية الغبية من الإنترنت لإعادة تعيين $ env؟

jzabroski تم https://github.com/PowerShell/PowerShell-RFC/pull/92 قد ترغب في أن تتناغم هناك.

قم بإنشاء نموذج كائن قياسي لموفري PowerShell: https://github.com/PowerShell/SHiPS/issues/66#issuecomment -368924485

في الرابط الخاص بإصدار SHiPS 66 ، أوجز أوامر cmdlets المحتملة للمرشح. ليس من الواضح بالنسبة لي سبب عدم تمكننا من تنفيذ شيء مثل سلوك Haskell typeclass لهذه أوامر cmdlets الأساسية.

واجهات برمجة التطبيقات هذه موجودة بالفعل في PowerShell.

iSazonov هل يمكنك تعديل ما ترد عليه

jzabroski ابحث عن الملفات في مجلد srcSystem.Management.Automationnamespaces.

يقوم POWERSHELL بهذا بشكل مختلف

إنه bash يقوم بذلك بشكل مختلف - يمكن لـ return فقط تعيين رمز إنهاء العملية (عدد صحيح) (ليس هذا ما يعنيه "return" في لغات البرمجة الأخرى ، إنه exit ) .

يمكن لـ PowerShell القيام بذلك أيضًا ، مع exit 5

إنه فقط أننا لا نستخدم أكواد الخروج كثيرًا في PowerShell (إلى حد كبير فقط للمهام المجدولة والتفاعل مع أنظمة تشغيل أخرى) ، لأنها ليست قشرة قائمة على العمليات ، ولا ينبغي إنهاء الوظائف.

في نهاية اليوم ، هذا هو السبب نفسه الذي يجعل اكتشاف نوع مقبض stdout غير مفيد في PowerShell (ولماذا "إعادة التوجيه" إلى out-null لا يماثل الإرسال إلى [void] أو التعيين إلى $null )

أوصي بأن يقدم الأشخاص مشكلات جديدة إذا كان لديهم بالفعل تعليقات يريدون التصرف بناءً عليها - نظرًا لأن الفريق _ بشكل واضح ولا لبس فيه قد استبعد إصدارًا غير متوافق مع الإصدارات السابقة من PowerShell ، لا أعرف سبب استمرار هذا الموضوع ...

نظرًا لأن الفريق _ بشكل واضح وصريح استبعد _ إصدار غير متوافق مع الإصدارات السابقة من

هذا خبر بالنسبة لي. كيف هذا واضح؟ يرجى تقديم روابط للوظائف أو الوثائق الأخرى.

إنه لأمر محبط بعض الشيء أن يسمع بعضنا "لن نكسر التوافق أبدًا" بينما نتصارع مع بعض الانكسار كل يوم. الهدف من هذا الخيط هو أن السوق الحرة للأفكار يمكن أن تحل بعض هذه المشاكل عندما لا تفعل المنبع.

قد يجد شخص ما أنه من المفيد للغاية أن يتفكك بوويرشيل ويخلق نسخة بأقل ديون تقنية. ستستفيد تلك المجموعة من الأفكار المطروحة في هذا الموضوع. (هذه هي الطريقة التي يعمل بها العالم الآن. أتمنى أن يفوز أفضل باورشيل.)

سأكرر أن الفريق قد أنتج بالفعل نسخة "غير متوافقة" من بوويرشيل من خلال إعادة تسمية الأمر من بوويرشيل إلى pwsh. القوة (شل) هي قذيفة. وظيفة الصدفة هي أن تكون المادة اللاصقة للبشر التي تربط الأنظمة الرقمية ببعضها البعض. إنه ليس ثنائيًا مجمعًا مع الحد الأدنى من التبعيات الخارجية. حتى لغات البرمجة التقليدية تخطط وتجري تغييرات جذرية.

يقوم POWERSHELL بهذا بشكل مختلف

إنه bash يفعل ذلك بشكل مختلف - return يمكنه فقط تعيين رمز الخروج من العملية (عدد صحيح) (هذا ليس كذلك

أشعر بالفضول بشأن القذائف الأخرى. ماذا يعملون؟ korn ، csh ، إلخ.

إليك مقال يناقش بيان الإرجاع بلغات متعددة: https://en.wikipedia.org/wiki/Return_statement

يستدعي أن نظام التشغيل [shells] يسمح بإرجاع أشياء متعددة: كود الإرجاع والإخراج.

لدى فريقي مجموعة متنوعة من البرامج النصية التي تعمل فقط في PowerShell 5 على الرغم من أننا نستخدم PowerShell 6 قدر الإمكان. في تجربتي ، فإن الافتراض القائل بأن PowerShell متوافق تمامًا مع الإصدارات السابقة خاطئ بالتأكيد. هناك على الأقل بعض الحالات القصوى (على سبيل المثال: ErrorActionPreference لا تتصرف بشكل حدسي) والتي يجب بالتأكيد معالجتها على أنها تغيير مفاجئ - الحالات التي يكون فيها إجراء الإصلاح أقل "كسر" من عدم القيام بذلك.

chriskuech هل هناك مشكلة توضح بالتفصيل مشكلتك مع ErrorActionPreference ؟

@ SteveL-MSFT أعتقد أن الفسيفساء التي ربطها KirkMunro مباشرة أدناه chriskuech تعليقات هي المشكلة التي تبحث عنها. ونعم ، أضغط على كلمة Mosaic في محادثة تقنية.

أن قال،iSazonov مغلقةchriskuech القضية الأصلية على 1 أكتوبر 2018: انظر https://github.com/PowerShell/PowerShell/issues/7774

يبدو أن هذه الأشياء تستمر في الظهور ، بأشكال مختلفة ، وتواصل اللجنة إغلاق القضايا حولها.

jzabroski وجدت

لقد قدمت أيضًا مشكلة في الماضي حول أحد الأعراض: Invoke-WebRequest طرح خطأ في الإنهاء. لقد شاهدت شخصيًا العديد من الأشخاص مذهولين تمامًا حول النموذج المعياري الكامل try / catch للتعامل مع طلبات HTTP الفاشلة ، والذي يحدث لأن أساليب .NET الداخلية تتسبب في أخطاء الإنهاء. في كل حالة من الحالات الثلاث المختلفة ، رد المهندس بكلمة بذيئة عندما شرحت السلوك الأساسي ولماذا لن يتم حل المشكلة كما يُزعم.

للتلخيص ، إنهاء الأخطاء ينهي البرنامج النصي لأن منشئو PowerShell يعتقدون أن النص لا يمكن أن يتقدم منطقيًا إلى ما بعد الخطأ ، لكنني لا أعتقد أن هذا هو حرفيًا أي شخص سوى قرار المخطوطة على أساس كل حالة على حدة. يمكن أن يقرر الناسخ فقط ما إذا كان يريد البرنامج النصي إلى Stop ، SilentlyContinue ، Continue ، إلخ

(مماسي للقضية أعلاه)

إذا قام PowerShell بتنفيذ وضع "ZeroTechDebt" للاشتراك ، أعتقد بالتأكيد أنه يجب تعيين $ErrorActionPreference = "Stop" افتراضيًا. من الواضح أن هذا الإعداد لا معنى له في REPL وبالتالي لا يجب تعيينه افتراضيًا لجميع السيناريوهات ، ولكن حرفيًا تكون جميع النصوص البرمجية مسبوقة بـ $ErrorActionPreference = "Stop" لتمكين "البرمجة الدفاعية" وتتصرف مثل " لغة برمجة.

chriskuech إذا لم تكن قد قمت بذلك بالفعل ، فيرجى إلقاء نظرة على هذه المجموعة من طلبات التعليقات: https://github.com/PowerShell/PowerShell-RFC/pull/187. يتحدثون مباشرة إلى ما تتحدث عنه هنا دون الحاجة إلى إصدار جديد للديون التقنية الصفرية من PowerShell.

يمكنك أيضًا العثور على طلبات التعليقات الأربعة في مشكلات منفصلة في صفحة المشكلات في هذا الريبو إذا كان ذلك يسهل قراءتها / هضمها. فقط ابحث عن المشكلات المفتوحة التي نشرتها وستجدها

@ SteveL-MSFT هنا مشكلة مماثلة تعيق إنتاجيتي. ليس $ErrorActionPreference ولكن $ConfirmPreference :

يوجد أدناه برنامج نصي قبيح كتبته لإعداد أحجام قرص SQL Server إلى 64 كيلو بايت.

Import-Module Storage;

function Format-Drives
{
    # See https://stackoverflow.com/a/42621174/1040437 (Formatting a disk using PowerShell without prompting for confirmation)
    $currentconfirm = $ConfirmPreference
    $ConfirmPreference = 'none'

    Get-Disk | Where isOffline | Set-Disk -isOffline $false
    # The next line of this script is (almost) copy-pasted verbatim from: https://blogs.technet.microsoft.com/heyscriptingguy/2013/05/29/use-powershell-to-initialize-raw-disks-and-to-partition-and-format-volumes/
    Get-Disk | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle MBR -Confirm:$false -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize -IsActive | Format-Volume -FileSystem NTFS -AllocationUnitSize 64kb -Confirm:$false

    # See https://stackoverflow.com/a/42621174/1040437 (Formatting a disk using PowerShell without prompting for confirmation)
    $ConfirmPreference = $currentconfirm
}

Format-Drives

زوجان من النقاط الجانبية:

  1. وثائق Format-Volume تريد المزيد. مثالين فقط؟ والوثائق الرسمية ليست متزامنة مع الموقع: https://github.com/MicrosoftDocs/windows-powershell-docs/issues/1170
  2. لماذا أحتاج إلى الذهاب إلى StackOverflow لمعرفة كيفية تجنب واجهة المستخدم الرسومية للغة البرمجة النصية؟
  3. حقيقة أن هذا عرضة للخطأ / من الصعب بغباء الكتابة "دون تفكير" يؤكد فقط على المشكلات ذات الصلة مثل https://github.com/PowerShell/PowerShell-RFC/issues/198 - إنه مثال آخر على مدى وعد Bruce Payette في " PowerShell In Action "أنك تكتب فقط ما تعتقد أنه صحيح ويعمل ... هو خطأ كليًا تمامًا.
  4. راجع أيضًا مشكلة @ mklement0 : https://github.com/PowerShell/PowerShell/issues/4568

يتطلب -Version ليس لديه طريقة لتحديد إصدار أقصى

راجع: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires؟view=powershell-6

هذا أمر مزعج عندما تكتب وظائف متقدمة تقوم بتحميل مكتبات .NET Framework حيث تختلف API تمامًا بين .NET Framework و .NET Core ، مثل كيفية عمل AccessControl API.

jzabroski يمكنك تحديد العدد، ومع ذلك، لفصل ما يلي:

#requires -PSEdition Desktop
# versus
#requires -PSEdition Core

مجرد ملاحظة سريعة أن rjmholt قد بدأ رسميًا مناقشة حول كيفية تنفيذ وإدارة التغييرات العاجلة: # 13129.

بالإضافة إلى ذلك ، يعتبر # 6817 و # 10967 المزيد من السلوكيات التي تستحق المراجعة بمجرد السماح بتغيير التغييرات.
(لديهم نفس السبب الجذري ، موضح في https://github.com/PowerShell/PowerShell/issues/10967#issuecomment-561843650).

حقيقة أن , أقوى من + أمر منطقي ، لأن PowerShell يتعلق بالقوائم أكثر منه حول الأرقام. برأيي المتواضع.

rjmholt بدأ مناقشة رسميًا

يجب أن أقول أنه ليس أكثر رسمية من أي مناقشة أخرى

أرغب في إجراء فحص صارم على الواردات ووقت تحرير التوقيعات الوظيفية.
هل تفكر في تقديم دلالات استيراد جديدة مثل توفر وحدات EcmaScript النمطية؟
لا مزيد من تلوث مساحة الاسم العالمية. آليات الاستيراد البطيئة.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات