Wenn ich eine Funktion habe, die mehr als einen Zeichenfolgenparameter akzeptiert, scheint der erste Parameter alle ihm zugewiesenen Daten zu erhalten, und die verbleibenden Parameter werden als leer übergeben.
Ein schnelles Testskript:
Function Test([string]$arg1, [string]$arg2)
{
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
Test("ABC", "DEF")
Die erzeugte Ausgabe ist
$arg1 value: ABC DEF
$arg2 value:
Die richtige Ausgabe sollte sein:
$arg1 value: ABC
$arg2 value: DEF
Dies scheint zwischen v1 und v2 auf mehreren Computern konsistent zu sein, daher mache ich offensichtlich etwas falsch. Kann jemand genau darauf hinweisen, was?
powershell
Nasir
quelle
quelle
Test "ABC" "DEF"
Antworten:
Parameter bei Aufrufen von Funktionen in PowerShell (alle Versionen) sind durch Leerzeichen und nicht durch Kommas getrennt . Außerdem sind die Klammern völlig unnötig und verursachen einen Analysefehler in PowerShell 2.0 (oder höher), wenn er
Set-StrictMode
aktiv ist. Argumente in Klammern werden nur in .NET-Methoden verwendet.quelle
(1,2,3)
an eine Funktion wird effektiv als Array behandelt. ein einziges Argument. Wenn Sie Argumente im OO-Methodenstil verwenden möchten, verwenden Sie die folgenden Module:$m = new-module -ascustomobject { function Add($x,$y) { $x + $y } }; $m.Add(1,1)
Powershell
ist eine Shell-Sprache und es ist üblich, dass Shell-Sprachen Leerzeichen als Token-Trennzeichen verwenden. Ich würde nicht sagen ,Powershell
ist anders , hier zu sein, es ist direkt im Einklang mit anderen System - Standard - Shells wiecmd
,sh
,bash
usw.Die richtige Antwort wurde bereits gegeben, aber dieses Problem scheint weit genug verbreitet zu sein, um einige zusätzliche Details für diejenigen zu rechtfertigen, die die Feinheiten verstehen möchten.
Ich hätte dies nur als Kommentar hinzugefügt, aber ich wollte eine Illustration hinzufügen - ich habe dies aus meiner Kurzreferenztabelle zu PowerShell-Funktionen herausgerissen. Dies setzt voraus, dass die Signatur der Funktion f lautet
f($a, $b, $c)
:Somit kann man eine Funktion mit durch Leerzeichen getrennten Positionsparametern oder auftragsunabhängigen benannten Parametern aufrufen . Die anderen Fallstricke zeigen, dass Sie Kommas, Klammern und Leerzeichen kennen müssen.
Weitere Informationen finden Sie in meinem Artikel Down the Rabbit Hole: Eine Studie zu PowerShell-Pipelines, -Funktionen und -Parametern . Der Artikel enthält auch einen Link zur Kurzreferenz / Wandkarte.
quelle
Hier gibt es einige gute Antworten, aber ich wollte auf ein paar andere Dinge hinweisen. Funktionsparameter sind tatsächlich ein Ort, an dem PowerShell glänzt. Beispielsweise können Sie in erweiterten Funktionen wie folgt entweder benannte oder Positionsparameter haben:
Dann können Sie es entweder durch Angabe des Parameternamens aufrufen oder einfach Positionsparameter verwenden, da Sie diese explizit definiert haben. Beides würde also funktionieren:
Das erste Beispiel funktioniert, obwohl
Name
es als zweites bereitgestellt wird, da wir den Parameternamen explizit verwendet haben. Das zweite Beispiel basiert jedoch auf der Position und muss daherName
das erste sein. Wenn möglich, versuche ich immer, Positionen zu definieren, damit beide Optionen verfügbar sind.PowerShell kann auch Parametersätze definieren. Es verwendet dies anstelle der Methodenüberladung und ist wiederum sehr nützlich:
Jetzt nimmt die Funktion entweder einen Namen oder eine ID an, aber nicht beide. Sie können sie positionell oder namentlich verwenden. Da es sich um einen anderen Typ handelt, wird PowerShell dies herausfinden. All dies würde also funktionieren:
Sie können den verschiedenen Parametersätzen auch zusätzliche Parameter zuweisen. (Das war offensichtlich ein ziemlich einfaches Beispiel.) Innerhalb der Funktion können Sie bestimmen, welcher Parametersatz mit der Eigenschaft $ PsCmdlet.ParameterSetName verwendet wurde. Zum Beispiel:
In einer verwandten Randnotiz gibt es dann auch eine Parameterüberprüfung in PowerShell. Dies ist eine meiner Lieblingsfunktionen von PowerShell und macht den Code in Ihren Funktionen sehr sauber. Es gibt zahlreiche Validierungen, die Sie verwenden können. Einige Beispiele sind:
Im ersten Beispiel akzeptiert ValidatePattern einen regulären Ausdruck, der sicherstellt, dass der angegebene Parameter Ihren Erwartungen entspricht. Wenn dies nicht der Fall ist, wird eine intuitive Ausnahme ausgelöst, die Ihnen genau sagt, was falsch ist. In diesem Beispiel würde "Etwas" gut funktionieren, aber "Sommer" würde die Validierung nicht bestehen.
ValidateRange stellt sicher, dass der Parameterwert zwischen dem Bereich liegt, den Sie für eine Ganzzahl erwarten. Also würden 10 oder 99 funktionieren, aber 101 würde eine Ausnahme auslösen.
Ein weiteres nützliches ist ValidateSet, mit dem Sie ein Array akzeptabler Werte explizit definieren können. Wenn etwas anderes eingegeben wird, wird eine Ausnahme ausgelöst. Es gibt auch andere, aber das wahrscheinlich nützlichste ist ValidateScript. Dies erfordert einen Skriptblock, der mit $ true ausgewertet werden muss, sodass der Himmel die Grenze darstellt. Zum Beispiel:
In diesem Beispiel wird nicht nur versichert, dass $ Path vorhanden ist, sondern dass es sich um eine Datei handelt (im Gegensatz zu einem Verzeichnis) und die Erweiterung .csv hat. ($ _ bezieht sich auf den Parameter in Ihrem Skriptblock.) Sie können auch viel größere mehrzeilige Skriptblöcke übergeben, wenn diese Ebene erforderlich ist, oder mehrere Skriptblöcke verwenden, wie ich es hier getan habe. Es ist äußerst nützlich und sorgt für schöne, saubere Funktionen und intuitive Ausnahmen.
quelle
My_Function -NamedParamater "ParamValue"
Funktionsaufrufstils. Dies ist ein Muster, dem mehr PS-Skriptcode zur besseren Lesbarkeit folgen sollte.Sie rufen PowerShell-Funktionen ohne Klammern und ohne Verwendung des Kommas als Trennzeichen auf. Versuchen Sie es mit:
In PowerShell ist das Komma (,) ein Array-Operator, z
Es wird
$a
ein Array mit drei Werten festgelegt.quelle
quelle
Wenn Sie ein C # / Java / C ++ / Ruby / Python / Pick-A-Language-From-This-Century-Entwickler sind und Ihre Funktion mit Kommas aufrufen möchten, weil Sie dies immer getan haben, brauchen Sie etwas so was:
Ruf jetzt an:
und du wirst sehen
quelle
Wenn Sie nicht wissen (oder sich nicht darum kümmern), wie viele Argumente Sie an die Funktion übergeben, können Sie auch einen sehr einfachen Ansatz verwenden, z.
Code :
Das würde alle Argumente ausdrucken. Zum Beispiel:
Ausgabe
Ich finde dies besonders nützlich, wenn ich Funktionen erstelle, die externe Befehle verwenden, die viele verschiedene (und optionale) Parameter haben können, sich aber auf diesen Befehl stützen, um Feedback zu Syntaxfehlern usw. zu geben.
Hier ist ein weiteres Beispiel aus der Praxis (Erstellen einer Funktion für den Befehl tracert, die ich nicht gerne an den abgeschnittenen Namen erinnern muss).
Code :
quelle
Wenn du es versuchst:
du erhältst:
Sie sehen also, dass die Klammern die Parameter trennen
Wenn du es versuchst:
du erhältst:
Jetzt könnten Sie eine unmittelbare Nützlichkeit der Klammern finden - ein Leerzeichen wird nicht zum Trennzeichen für den nächsten Parameter - stattdessen haben Sie eine Auswertungsfunktion.
quelle
@
wie dieses leere Array mit einem at-Zeichen ( ) vor dem führenden Paren definiert :@()
; oder dieses Array mit zwei Zahlen :@(1, 2)
.Da dies eine häufig gestellte Frage ist, möchte ich erwähnen, dass eine PowerShell-Funktion genehmigte Verben verwenden sollte ( Verb-Nomen als Funktionsname). Der Verbteil des Namens gibt die Aktion an, die das Cmdlet ausführt. Der Substantivteil des Namens identifiziert die Entität, für die die Aktion ausgeführt wird. Diese Regel vereinfacht die Verwendung Ihrer Cmdlets für fortgeschrittene PowerShell-Benutzer.
Sie können auch festlegen, ob der Parameter obligatorisch ist und an welcher Position der Parameter steht:
Um den Parameter an die Funktion zu übergeben, können Sie entweder die Position verwenden :
Oder Sie geben die Parameternamen :
Sie verwenden keine Klammern wie beim Aufrufen einer Funktion in C #.
Ich würde empfehlen, immer die Parameternamen zu übergeben, wenn mehr als ein Parameter verwendet wird, da dies besser lesbar ist .
quelle
Get-Node
Cmdlet. Es wäre für uns klar, dass wir zu berufen habenGet-Node
, nichtRetrieve-Node
, nochReceive-Node
, noch .....Ich weiß nicht, was Sie mit der Funktion machen, aber schauen Sie sich das Schlüsselwort 'param' an. Es ist viel leistungsfähiger, um Parameter an eine Funktion zu übergeben, und macht es benutzerfreundlicher. Unten finden Sie einen Link zu einem übermäßig komplexen Artikel von Microsoft darüber. Es ist nicht so kompliziert, wie der Artikel es klingen lässt.
Param Verwendung
Hier ist auch ein Beispiel aus einer Frage auf dieser Site:
Hör zu.
quelle
quelle
Ich habe vorhin Folgendes angegeben:
Das häufigste Problem ist die Verwendung der Singularform
$arg
, die falsch ist. Es sollte immer Plural sein als$args
.Das Problem ist nicht das. In der Tat
$arg
kann alles andere sein. Das Problem war die Verwendung des Kommas und der Klammern.Ich führe den folgenden Code aus, der funktioniert hat, und die Ausgabe folgt:
Code:
Test "ABC" "DEF"
Ausgabe:
quelle
Dies ist eine ordnungsgemäße
params
Erklärung.Siehe about_Functions_Advanced_Parameters .
Und es funktioniert tatsächlich.
quelle
Sie können Parameter in einer Funktion wie dieser auch übergeben:
quelle
Ich sehe es hier nicht erwähnt, aber das Aufteilen Ihrer Argumente ist eine nützliche Alternative und wird besonders nützlich, wenn Sie die Argumente für einen Befehl dynamisch erstellen (im Gegensatz zur Verwendung
Invoke-Expression
). Sie können mit Arrays für Positionsargumente und Hashtabellen für benannte Argumente splat. Hier sind einige Beispiele:Splat mit Arrays (Positionsargumente)
Testverbindung mit Positionsargumenten
Mit Array-Splatting
Splat With Hashtable (benannte Argumente)
Testverbindung mit benannten Argumenten
Mit Hashtable Splatting
Positive und benannte Argumente gleichzeitig teilen
Testverbindung mit Positions- und benannten Argumenten
Array und Hashtables zusammen teilen
quelle