2009-08-15 8 views
5

विंडोज शक्तियों में, मैं एक स्ट्रिंग में एक चाल कमांड को स्टोर करने की कोशिश कर रहा हूं और फिर इसे निष्पादित करता हूं। क्या कोई मुझे बता सकता है कि यह क्यों काम नहीं करता है?मैं शक्तियों में स्ट्रिंग से तर्क के साथ कमांडलेट निष्पादित क्यों नहीं कर सकता?

PS C:\Temp\> dir 
    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Temp 

Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---   8/14/2009 8:05 PM  2596 sa.csproj 
-a---   8/15/2009 10:42 AM   0 test.ps1 


PS C:\Temp> $str = "mv sa.csproj sb.csproj" 
PS C:\Temp> &$str 
The term 'mv sa.csproj sb.csproj' is not recognized as a cmdlet, function, operable program, or script file. Verify the 
term and try again. 
At line:1 char:2 
+ &$ <<<< str 
PS C:\Temp> 

तर्कों के साथ किसी भी आदेश को संग्रहीत करते समय मुझे यह त्रुटि मिलती है। मैं इस सीमा को कैसे दूर करूं?

उत्तर

10

मदद से (about_Operators):

 
& Call operator 
    Description: Runs a command, script, or script block. Because the call 
    operator does not parse, it cannot interpret command parameters.

आप एक स्ट्रिंग के बजाय एक स्क्रिप्ट ब्लॉक का उपयोग कर सकते हैं:

$s = { mv sa.csproj sb.csproj } 
& $s 

या आप उपयोग कर सकते हैं Invoke-Expression:

Invoke-Expression $str 

या

iex $str 

&, Invoke-Expression स्ट्रिंग सामग्री को पार्स करते हैं, तो आप केवल एक ही कमांड में कुछ भी नहीं डाल सकते हैं।

+0

धन्यवाद है आपको लगता है कि आप (लिंक करने के लिए या) व्याख्या कर सकते हैं और चरित्र क्या करता है की एक विवरण करते हैं? –

+2

'&' सहायता राज्यों की तरह, एकल आदेश, स्क्रिप्ट या स्क्रिप्टब्लॉक निष्पादित करने के लिए है। यह कोई पार्सिंग नहीं करता है, इसलिए यह केवल एक ही तर्क स्वीकार करता है जिसे तब एक अनावश्यक आदेश माना जाता है। यदि आप पैरामीटर जोड़ना चाहते हैं, तो या तो स्क्रिप्ट या स्क्रिप्ट ब्लॉक में कॉल को लपेटें या 'Invoke-Expression' का उपयोग करें। पावरहेल में 'help about_operators' टाइप करके आप ऑपरेटरों का वर्णन करने वाले सहायता पृष्ठ को पा सकते हैं। – Joey

5

सभी जोहान्स सुझाव स्पॉट पर हैं लेकिन मैं लोगों को जागरूक करना चाहता हूं कि वी 2 में एक और विकल्प है। आप पहले की तरह एक स्ट्रिंग में आदेश डाल, लेकिन आप एक hashtable में पैरामीटर डाल दिया और & उदा .:

$cmd = 'mv' 
$params = @{Path = 'log.txt'; Destination = 'log.bak'} 
&$cmd @params 

का उपयोग कर इस splatting नामक एक नया सं 2 विशेषता का उपयोग करता आह्वान। यह एक कमांड के लिए प्रतिक्रिया फ़ाइल का उपयोग करने जैसा है लेकिन आप पैरामीटर को फ़ाइल के बजाय हैशटेबल में डालते हैं।

नोट: यदि आप भी एक सरणी जो पैरामीटर "स्थितीय द्वारा" में प्लग होगा बजाय नाम जैसे द्वारा में पैरामीटर डाल सकते हैं:

$cmd = "cpi" 
$params = ('log.txt', 'log.bak') 
&$cmd @params 

यह बिल्कुल ओपी की समस्या नहीं हो सकती है लेकिन यह एक है के बारे में जानने लायक चाल।

2

मैं एक समय पहले तर्कों की सूची के निर्माण के बाद एक बाहरी कार्यक्रम लागू के बारे में एक ऐसी ही सवाल का जवाब देने के लिए किया था:

की जांच की गई और यह . $program $argString या & $program $argString का उपयोग कर काम नहीं करता है, तो $argString कई तर्क होता है की तरह लग रहा । . और & ऑपरेटर केवल एक ही तर्क के रूप में पूरे $argString को पारित करते हुए प्रत्यक्ष कॉल करते हैं।

इसके बजाय [string]$argString का उपयोग करने और $argString += "-aaa `"b b b`"" करने का

, आप इसे [string[]]$argArray को बदल सकते हैं और $argArray += @('-aaa', 'b b b'), जो काम करेगा और स्वचालित रूप से आवश्यक के रूप में तार बच जाएंगे इस्तेमाल कर सकते हैं।

आप $process = [Diagnostics.Process]::Start($program, $argString) का भी उपयोग कर सकते हैं। इससे निष्पादन प्रगति को ट्रैक करना आसान हो जाएगा, लेकिन किसी भी पाठ आउटपुट को पुनर्प्राप्त करना कठिन होगा।

या आप सब कुछ एक स्ट्रिंग में डाल सकते हैं और Invoke-Expression "$program $argString" का उपयोग कर सकते हैं, जो पूरे स्ट्रिंग को कमांड के रूप में पार्स करेगा और इसे सही तरीके से निष्पादित करेगा।

Keith उल्लेख किया है, splatting, PowerShell में एक और अच्छा विकल्प 2.

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