about_Parsing
Kort beskrivning
Beskriver hur PowerShell parsar kommandon.
Lång beskrivning
När du anger ett kommando i kommandotolken delar PowerShell upp kommandotexten i en serie segment som kallas token och bestämmer sedan hur varje token ska tolkas.
Om du till exempel skriver:
Write-Host book
PowerShell delar upp kommandot i två token Write-Host och book, och tolkar varje token oberoende av varandra med något av två huvudsakliga parsningslägen: uttrycksläge och argumentläge.
Anteckning
När PowerShell parsar kommandoindata försöker den matcha kommandonamnen till cmdletar eller inbyggda körbara filer. Om ett kommandonamn inte har någon exakt matchning förbereder Get- PowerShell kommandot som standardverb. PowerShell parsar Service till exempel som Get-Service. Vi rekommenderar inte att du använder den här funktionen av följande skäl:
- Det är ineffektivt. Detta gör att PowerShell söker flera gånger.
- Externa program med samma namn löses först, så du kanske inte kör den avsedda cmdleten.
Get-HelpochGet-Commandkänner inte igen verblösa namn.- Kommandonamnet kan vara ett reserverat ord eller ett språknyckelord.
Processär både och och kommer inte att matcha tillGet-Process.
Uttrycksläge
Uttrycksläget är avsett att kombinera uttryck som krävs för värdemanipulering på ett skriptspråk. Uttryck är representationer av värden i PowerShell-syntax och kan vara enkla eller sammansatta, till exempel:
Literaluttryck är direkta representationer av deras värden:
'hello'
32
Variabeluttryck har värdet för variabeln som de refererar till:
$x
$script:path
Operatorer kombinerar andra uttryck för utvärdering:
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- Teckensträngliteraler måste finnas inom citattecken.
- Tal behandlas som numeriska värden snarare än som en serie tecken (om de inte är undantagna).
- Operatorer, inklusive unary operatorer som
-och-notbinära operatorer som+och-gt, tolkas som operatorer och tillämpar sina respektive åtgärder på sina argument (operander). - Attribut- och konverteringsuttryck parsas som uttryck och tillämpas på underordnade uttryck, t.ex.
[int] '7'. - Variabelreferenser utvärderas till deras värden, men splatting (dvs. klistra in förfyllda parameteruppsättningar) är förbjudet och orsakar ett parserfel.
- Allt annat behandlas som ett kommando som ska anropas.
Argumentläge
Vid parsning ser PowerShell först ut att tolka indata som ett uttryck. Men när ett kommandoanrop påträffas fortsätter parsningen i argumentläge. Om du har argument som innehåller blanksteg, till exempel sökvägar, måste du omsluta argumentvärdena med citattecken.
Argumentläget är utformat för att parsa argument och parametrar för kommandon i en gränssnittsmiljö. Alla indata behandlas som en expanderbar sträng om den inte använder någon av följande syntaxer:
Dollartecken (
$) följt av ett variabelnamn börjar en variabelreferens, annars tolkas den som en del av den expanderbara strängen. Variabelreferensen kan innehålla medlemsåtkomst eller indexering.- Ytterligare tecken som följer enkla variabelreferenser, till exempel
$HOME, anses vara en del av samma argument. Omslut variabelnamnet i klammerparenteser ({}) för att separera det från efterföljande tecken. Till exempel${HOME}. - När variabelreferensen innehåller medlemsåtkomst anses det första av ytterligare tecken vara början på ett nytt argument. Till exempel
$HOME.Length-moreresulterar i två argument: värdet$HOME.Lengthför och strängliteral-more.
- Ytterligare tecken som följer enkla variabelreferenser, till exempel
Citattecken (
'och") börjar strängarKlammerparenteser (
{}) påbörjar ett nytt skriptblockKommatecken (
,) introducerar listor som skickas som matriser, förutom när kommandot som ska anropas är ett inbyggt program, i vilket fall de tolkas som en del av den expanderbara strängen. Initiala, efterföljande eller avslutande kommatecken stöds inte.Parenteser (
()) påbörjar ett nytt uttryckUnderuttrycksoperatorn (
$()) påbörjar ett inbäddat uttryckInitial vid tecken (
@) börjar uttryckssyntaxer som splatting (@args), matriser (@(1,2,3)) och hashtabellliteraler (@{a=1;b=2}).(),$()och@()i början av en token skapar du en ny parsningskontext som kan innehålla uttryck eller kapslade kommandon.- När det följs av ytterligare tecken betraktas det första ytterligare tecknet som början på ett nytt, separat argument.
- När föregås av en icke-quoted literal
$()fungerar som en expanderbar sträng,()startar ett nytt argument som är ett uttryck och@()tas som literal@med()att starta ett nytt argument som är ett uttryck.
Allt annat behandlas som en expanderbar sträng, förutom metakarakter som fortfarande behöver fly.
- Argumentlägesmetacharacters (tecken med särskild syntaktisk betydelse) är:
<space> ' " ` , ; ( ) { } | & < > @ #. Av dessa< > @ #är bara speciella i början av en token.
- Argumentlägesmetacharacters (tecken med särskild syntaktisk betydelse) är:
Token för stoppparsning (
--%) ändrar tolkningen av alla återstående argument. Mer information finns i avsnittet om att stoppa parsningstoken nedan.
Exempel
Följande tabell innehåller flera exempel på token som bearbetas i uttrycksläge och argumentläge och utvärdering av dessa token. För dessa exempel är 4värdet för variabeln $a .
| Exempel | Läge | Resultat |
|---|---|---|
2 |
Uttryck | 2 (heltal) |
`2 |
Uttryck | "2" (kommando) |
Write-Output 2 |
Uttryck | 2 (heltal) |
2+2 |
Uttryck | 4 (heltal) |
Write-Output 2+2 |
Argument | "2+2" (sträng) |
Write-Output(2+2) |
Uttryck | 4 (heltal) |
$a |
Uttryck | 4 (heltal) |
Write-Output $a |
Uttryck | 4 (heltal) |
$a+2 |
Uttryck | 6 (heltal) |
Write-Output $a+2 |
Argument | "4+2" (sträng) |
$- |
Argument | "$-" (kommando) |
Write-Output $- |
Argument | "$-" (sträng) |
a$a |
Uttryck | "a$a" (kommando) |
Write-Output a$a |
Argument | "a4" (sträng) |
a'$a' |
Uttryck | "a$a" (kommando) |
Write-Output a'$a' |
Argument | "a$a" (sträng) |
a"$a" |
Uttryck | "a$a" (kommando) |
Write-Output a"$a" |
Argument | "a4" (sträng) |
a$(2) |
Uttryck | "a$(2)" (kommando) |
Write-Output a$(2) |
Argument | "a2" (sträng) |
Varje token kan tolkas som någon typ av objekttyp, till exempel boolesk eller sträng. PowerShell försöker fastställa objekttypen från uttrycket. Objekttypen beror på vilken typ av parameter ett kommando förväntar sig och om PowerShell vet hur argumentet ska konverteras till rätt typ. I följande tabell visas flera exempel på de typer som tilldelats värden som returneras av uttrycken.
| Exempel | Läge | Resultat |
|---|---|---|
Write-Output !1 |
-argument | "!1" (sträng) |
Write-Output (!1) |
uttryck | Falskt (booleskt) |
Write-Output (2) |
uttryck | 2 (heltal) |
Set-Variable AB A,B |
-argument | 'A','B' (matris) |
CMD /CECHO A,B |
-argument | 'A,B' (sträng) |
CMD /CECHO $AB |
uttryck | "A B" (matris) |
CMD /CECHO :$AB |
-argument | ':A B' (sträng) |
Skicka argument till interna kommandon
När du kör interna kommandon från PowerShell parsas argumenten först av PowerShell. De parsade argumenten kopplas sedan till en enda sträng med varje parameter avgränsad med ett blanksteg.
Följande kommando anropar till exempel programmet icacls.exe .
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Om du vill köra det här kommandot i PowerShell 2.0 måste du använda escape-tecken för att förhindra att PowerShell feltolkar parenteserna.
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
Stoppparsningstoken
Från och med PowerShell 3.0 kan du använda stoppparsningstoken (--%) för att hindra PowerShell från att tolka indata som PowerShell-kommandon eller -uttryck.
Anteckning
Token för stoppparsning är endast avsedd att användas på Windows-plattformar.
När du anropar ett internt kommando placerar du stop-parsing-token före programargumenten. Den här tekniken är mycket enklare än att använda escape-tecken för att förhindra feltolkning.
När den påträffar en stoppparsningstoken behandlar PowerShell de återstående tecknen på raden som en literal. Den enda tolkning som utförs är att ersätta värden för miljövariabler som använder Standard Windows-notation, till exempel %USERPROFILE%.
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
PowerShell skickar följande kommandosträng till programmet icacls.exe :
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Token för stoppparsning gäller endast fram till nästa nyrads- eller pipelinetecken. Du kan inte använda ett fortsättningstecken (`) för att utöka dess effekt eller använda en kommandogränsare (;) för att avsluta dess effekt.
Förutom %variable% miljövariabelreferenser kan du inte bädda in andra dynamiska element i kommandot. Undantag från ett % tecken som %%, som du kan göra i batchfiler, stöds inte. %<name>% token expanderas alltid. Om <name> inte refererar till en definierad miljövariabel skickas token som den är.
Du kan inte använda strömomdirigering (till exempel >file.txt) eftersom de skickas ordagrant som argument till målkommandot.
Skicka argument som innehåller citattecken
Vissa interna kommandon förväntar sig argument som innehåller citattecken. Normalt tar PowerShells kommandoradsparsning bort citattecknet som du angav. De parsade argumenten kopplas sedan till en enda sträng med varje parameter avgränsad med ett blanksteg. Den här strängen tilldelas sedan egenskapen Argument för ett ProcessStartInfo objekt. Citattecken i strängen måste vara undantagna med extra citattecken eller omvänt snedstreck (\).
Anteckning
Omvänt snedstreck (\) känns inte igen som ett escape-tecken av PowerShell. Det är escape-tecknet som används av det underliggande API:et för ProcessStartInfo.Arguments.
Mer information om escape-kraven finns i dokumentationen för ProcessStartInfo.Arguments.
I följande exempel används TestExe.exe verktyget . Det här verktyget används av Pester-testerna i PowerShell-källdatabasen. Målet med de här exemplen är att skicka katalogsökvägen "C:\Program Files (x86)\Microsoft\" till ett internt kommando så att den tog emot sökvägen som en citerad sträng.
Parametern TestExeechoargs i visar de värden som tas emot som argument till den körbara filen. Du kan använda det här verktyget för att kontrollera att du har undantagit tecknen i argumenten korrekt.
TestExe -echoargs """""${env:ProgramFiles(x86)}\Microsoft\\"""""
TestExe -echoargs """""C:\Program Files (x86)\Microsoft\\"""""
TestExe -echoargs "\""C:\Program Files (x86)\Microsoft\\"""
TestExe -echoargs --% "\"C:\Program Files (x86)\Microsoft\\"
TestExe -echoargs --% """C:\Program Files (x86)\Microsoft\\""
TestExe -echoargs --% """%ProgramFiles(x86)%\Microsoft\\""
Utdata är desamma för alla exempel:
Arg 0 is <"C:\Program Files (x86)\Microsoft\">
Du kan skapa TestExe från källkoden. Se TestExe.
Skicka argument till PowerShell-kommandon
Från och med PowerShell 3.0 kan du använda token för slutparametrar (--) för att stoppa PowerShell från att tolka indata som PowerShell-parametrar. Detta är en konvention som anges i POSIX Shell- och Utilities-specifikationen.
Token för slutparametrar (--) anger att alla argument som följer den ska skickas i sin faktiska form som om dubbla citattecken placerades runt dem. Om du till exempel använder -- kan du mata ut strängen -InputObject utan att använda citattecken eller tolka den som en parameter:
Write-Output -- -InputObject
-InputObject
Till skillnad från stoppparsningstoken (--%) kan alla värden som följer -- token tolkas som uttryck av PowerShell.
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
Det här beteendet gäller endast PowerShell-kommandon. Om du använder -- token när du anropar ett externt kommando skickas strängen -- som ett argument till det kommandot.
TestExe -echoargs -a -b -- -c
Utdata visar att -- skickas som ett argument till TestExe.
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>
Experimentell funktion
PowerShell 7.2 innehåller den experimentella funktionen PSNativeCommandArgumentPassing . När den här experimentella funktionen är aktiverad använder PowerShell egenskapen StartProcessInfoArgumentList för objektet i stället för vår nuvarande mekanism för att rekonstruera en sträng när du anropar en intern körbar fil.
Mer information finns i PSNativeCommandArgumentPassing.