2014-05-13 51 views
6

這個問題類似於Passing empty arguments to executables using powershell,但我想擴大問題和答案,並理解「爲什麼」更好,因爲它看起來像一個PowerShell陷阱。爲什麼PowerShell在命令行上處理空字符串的方式不同?

如果加載了PSCX和運行echoargs(外部命令,即EXE文件),你可以看到,空字符串參數被跳過:

PS> echoargs word "two words" "" 123 
Arg 0 is <word> 
Arg 1 is <two words> 
Arg 2 is <123> 

但是如果你使用了「CMD越獄」( --%)你可以把它顯得「正常」:

PS> echoargs --% word "two words" "" 123 
Arg 0 is <word> 
Arg 1 is <two words> 
Arg 2 is <> 
Arg 3 is <123> 

同樣,如果一個寫一個PowerShell功能空字符串處理不當:

PS> Show-Args word "two words" "" 123 
Arg 0 is <word> 
Arg 1 is <two words> 
Arg 2 is <> 
Arg 3 is <123> 

由於以下原因,這種差異對我來說似乎是一件大事。上面顯示的例子在命令行中使用了一個空字符串,所以至少你有一個問題的提示。 但是,如果使用包含空字符串的變量,結果完全相同。這意味着人們必須要麼:

  1. 嚴格察所有變量被饋送到外部命令,或者
  2. 使用CMD逃逸( - %)和使用任何PowerShell的就行
  3. 的其餘部分構造放棄
  4. 每個參數報價外部命令用反引號/雙引號像`"this`"`"$this`"`"`"

...或不好的事情會發生!

(@KeithHill指出了第三個解決方法上面,所以我說在那兒的完整性。它爲文字或變量,這樣,雖然難看,也許是三種解決方法的最佳選擇。)

所以PowerShell處理函數的參數與外部命令的參數不同 - 非常顯着。這是PowerShell行爲中的不一致嗎?如果不是,爲什麼不呢?


補遺

作爲參考,這裏是上面所用的PowerShell的功能體:

function Show-Args() 
{ 
    for ($i = 0; $i -lt $args.length; $i++) 
    { 
     Write-Host ("Arg {0} is <{1}>" -f $i, $args[$i]) 
    } 
} 

這裏是一個echoargs相當於在C#:

class Program 
{ 
    static void Main(string[] args) 
    { 
     for (int i = 0; i < args.Length; i++) 
     { 
      System.Console.WriteLine("Arg {0} is <{1}>", i, args[i]); 
     } 
    } 
} 

回答

2

的行爲可能被認爲是「按設計」(這很難說確實基於實施和測試),但我認爲這件事沒有多少考慮,你提出了優秀的觀點。

我個人認爲你是對的,PowerShell是不一致的。值得考慮的是要保持一致,儘管這樣做有破壞現有腳本的風險。

+1

是的,對應用程序的空字符串參數的處理看起來,這個錯誤。 ;-)公平地說,這個問題至少存在於V2之前。 –

相關問題