2011-02-16 7 views
9

यह कुछ अविश्वसनीय है। test.ps1 स्क्रिप्ट के साथ फ़ोल्डर और इसे चलाने के लिएपावरशेल mkdir ऊर्फ + सेट-स्ट्रिक्टोड-संस्करण 2. अजीब बग। क्यूं कर?

Set-StrictMode -Version 2 
mkdir c:\tmp\1 # same with 'md c:\tmp\1' 

प्रारंभ cmd.exe, नेविगेट:

c:\tmp>powershell ".\test.ps1" 

यह पैदा करता है निम्न त्रुटि:

The variable '$_' cannot be retrieved because it has not been set. 
At line:50 char:38 
+   $steppablePipeline.Process($_ <<<<) 
    + CategoryInfo   : InvalidOperation: (_:Token) [], ParentContainsEr 
    rorRecordException 
    + FullyQualifiedErrorId : VariableIsUndefined 

यह test.ps1 फ़ाइल में एक PowerShell कोड स्निपेट है क्यूं कर?

यह PowerShell कंसोल से शुरू होने पर काम करता है लेकिन cmd.exe नहीं। मैंने इस बग को बहुत बड़ी लिपि में खोजा। यह एक डब्ल्यूटीएफ पल था।

इस साधारण लिपि में क्या गलत है?

उत्तर

14

हालांकि एक कामकाज पहले ही पाया जा चुका है, मैंने सोचा कि लोगों को स्पष्टीकरण में रुचि हो सकती है।

कारण है कि यह cmd.exe बनाम खोल में अलग ढंग से व्यवहार करती है के रूप में, देखने के Powershell 2.0 - Running scripts for the command line call vs. from the ISE

संदर्भ में उल्लेख किया है, वहाँ के बाद दो आदेशों के बीच एक अंतर है:

powershell ".\test.ps1" 
powershell -File ".\test.ps1" 

का उपयोग करते समय पहला वाक्यविन्यास, यह गुंजाइश के साथ गड़बड़ प्रतीत होता है, जिससे सेट-स्ट्रिक्टोड कमांड वैश्विक स्तर पर परिभाषित कार्यों के लिए सख्त मोड को संशोधित करने का कारण बनता है।

यह mkdir फ़ंक्शन की परिभाषा में एक बग (या गलत धारणा, शायद) ट्रिगर करता है।

फ़ंक्शन न्यू-आइटम cmdlet के लिए पाइपलाइन प्रॉक्सी करने के लिए GetSteppablePipeline विधि का उपयोग करता है। हालांकि, लेखक ने इस तथ्य के लिए इस बात की उपेक्षा की कि पाइपलाइन में कुछ भी नहीं होने पर भी प्रोसेस अनुभाग अभी भी निष्पादित किया गया है। इस प्रकार, जब प्रोसेस अनुभाग तक पहुंच जाता है, तो $ _ स्वचालित चर परिभाषित नहीं किया जाता है। यदि सख्त मोड सक्षम है, तो एक अपवाद होगा।

निम्नलिखित लाइन को बदलने के लिए माइक्रोसॉफ्ट इस खाते के लिए किया जाएगा के लिए एक ही रास्ता:

$steppablePipeline.Process($_) 
निम्नलिखित के साथ

:

if (test-path Variable:Local:_) { 
     $steppablePipeline.Process($_) 
    } 

मैं स्वीकार करते हैं कि इस का सबसे अच्छा तरीका यह तय करने के लिए नहीं किया जा सकता , लेकिन उपरांत नगण्य होगा। एक अन्य विकल्प किसी भी तरह परीक्षण करना होगा यदि पाइपलाइन BEGIN अनुभाग में खाली है, और उसके बाद $ _ से $ null सेट करें।

किसी भी तरह से, यदि आप "powerhell.exe -File फ़ाइल नाम" वाक्यविन्यास के साथ अपनी स्क्रिप्ट चलाते हैं, तो आपको इसके बारे में चिंता करने की आवश्यकता नहीं होगी।

+0

क्लब में आपका स्वागत है! वास्तव में बहुत अच्छी जांच। –

2

यह एक बग (पावरशेल में) जैसा दिखता है।

+3

मैंने वर्कअराउंड के रूप में 'न्यू-आइटम' ब्लाह 'टाइप प्रकार' का उपयोग किया। समस्या केवल 'mkdir' और' md' aliases – Roman

+0

के साथ होती है, मैं इस उत्तर को स्वीकार करने जा रहा हूं, लेकिन टिप्पणी के साथ "अपनी पावरशेल स्क्रिप्ट में उपनामों का उपयोग करने से बचें और आपके पास ऐसी कोई अजीब समस्या नहीं होगी"। – Roman

+0

लेकिन यह उपनाम के बारे में नहीं है। 'mkdir' एक फ़ंक्शन है और सख्त मोड चालू होने पर इसमें कोई समस्या है। –

संबंधित मुद्दे