2014-05-13 7 views
6

Diese Frage ist ähnlich wie Passing empty arguments to executables using powershell aber ich möchte sowohl die Frage als auch die Antwort erweitern und das "Warum" besser verstehen, weil es wie ein PowerShell-Fallstrick aussieht.Warum behandelt PowerShell leere Zeichenfolgen in der Befehlszeile anders?

Wenn Sie sich PSCX laden und echoargs (einen externen Befehl, dh eine exe-Datei) ausführen Sie können sehen, dass der leere String-Argument übersprungen wird:

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

Aber wenn Sie die „CMD escape“ verwenden (

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

Ähnlich, wenn man eine Powershell-Funktion die leere Zeichenkette schreibt richtig behandelt:

) Sie können es „richtig“ erscheinen

Dieser Unterschied scheint mir aus dem folgenden Grund eine große Sache zu sein. Die oben gezeigten Beispiele verwenden eine leere Zeichenfolge in der Befehlszeile, so dass Sie zumindest einen Hinweis auf das Problem haben. Aber die Ergebnisse sind genau die gleichen, wenn man eine Variable verwendet, die eine leere Zeichenfolge enthält. Welche ein Mittel hat, um entweder:

  1. rigoros alle Variablen Polizei externe Befehle zugeführt werden, oder
  2. das Entweichen CMD verwenden (-%) und unter Verwendung eines beliebigen verzichten Power auf dem Rest der Linie konstruiert
  3. zitieren jedes Argument auf einen externen Befehl mit Backquote/doppelten Anführungszeichen wie `"this`" oder `"$this`" oder `"`"

... oder schlechte Dinge passieren! So

(@KeithHill wies auf die dritte Problemumgehung aus oben so auf Vollständigkeit ich es dort gegeben. Es ist für oder Variable, funktioniert so, obwohl hässlich, vielleicht ist die beste Wahl der drei Abhilfen.)

PowerShell behandelt Argumente für eine Funktion anders als Argumente für einen externen Befehl - dramatisch. Ist dies eine Inkonsistenz im Verhalten von PowerShell? Wenn nicht, warum nicht?


Nachtrag

Als Referenz ist hier die Funktion Powershell-Körper oben verwendet:

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

Und hier ist ein EchoArgs-Äquivalent in 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]); 
     } 
    } 
} 

Antwort

2

Die Verhalten kann "von Entwurf" betrachtet werden (es ist schwer zu kn sicher, basierend auf der Implementierung und den Tests), aber ich denke nicht, dass die Sache gründlich überdacht wurde und Sie hervorragende Punkte bekommen.

Persönlich denke ich, dass Sie Recht haben und PowerShell ist inkonsistent. Es lohnt sich, eine Änderung als konsistent zu betrachten, obwohl dies ein gewisses Risiko birgt, bestehende Skripts zu zerstören.

+1

Ja, die Handhabung von leeren String-Argumente zu Anwendungen scheint, äh, falsch. ;-) Um fair zu sein, existiert dieses Problem mindestens so weit zurück wie V2. –

Verwandte Themen