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 avgör sedan hur varje token ska tolkas.

Om du till exempel skriver:

Write-Host book

PowerShell delar upp kommandot i två token, och , och tolkar varje token oberoende av varandra med hjälp av ett av två huvudsakliga Write-Host book parsningsläge: uttrycksläge och argumentläge.

Anteckning

När PowerShell parsar kommandoindata försöker det matcha kommandonamnen med cmdlets eller interna körbara filer. Om ett kommandonamn inte har en exakt matchning, kommer PowerShell att lägga till kommandot Get- som ett standardverb. PowerShell parsar till exempel Process som Get-Process . 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 matchas först, så du kan inte köra den avsedda cmdleten.
  • Get-Help och Get-Command känner inte igen verb-mindre namn.

Uttrycksläge

Uttrycksläget är avsett för att kombinera uttryck som krävs för värdemanipulering i 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ängslitteraler måste finnas inom citattecken.
  • Tal behandlas som numeriska värden i stället för som en serie tecken (om de inte är rymmna).
  • Operatorer, inklusive unära operatorer som och binära operatorer som och , tolkas som operatorer och tillämpar sina respektive åtgärder på sina - -not argument + -gt (operander).
  • Attribut- och konverteringsuttryck parsas som uttryck och tillämpas på underordnade uttryck, t.ex. [int] '7' .
  • Variabelreferenser utvärderas till sina värden men splattning (dvs. att klistra in förifyllda 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 parsning i argumentläge. Om du har argument som innehåller blanksteg, till exempel sökvägar, måste du omge argumentvärdena inom citattecken.

Argumentläget är utformat för parsning av 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 med en variabelreferens, annars tolkas det som en del av den expanderbara strängen. Variabelreferensen kan innehålla medlemsåtkomst eller indexering.

    • Ytterligare tecken som följer enkla variabelreferenser, $HOME till exempel , betraktas som en del av samma argument. Omslut variabelnamnet inom kparenteser ( {} ) för att skilja det från efterföljande tecken. Till exempel ${HOME}.
    • När variabelreferensen inkluderar medlemsåtkomst betraktas det första av eventuella ytterligare tecken som början på ett nytt argument. Till exempel $HOME.Length-more resulterar i två argument: värdet för och $HOME.Length stränglitteralen -more .
  • Citattecken ( ' och " ) börjar strängar

  • Kparenteser ( {} ) startar ett nytt skriptblock

  • Kommatecken ( ) 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. Inledande, efterföljande eller avslutande kommatecken stöds inte.

  • Parenteser ( () ) startar ett nytt uttryck

  • Subexpression-operatorn ( $() ) börjar ett inbäddat uttryck

  • Initialt vid tecknet ( @ ) börjar uttryckssyntaxer som splatting ( @args ), matriser ( ) och @(1,2,3) hash-tabelllitteraler ( @{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örsta extra tecknet följs av ytterligare tecken betraktas det som början på ett nytt, separat argument.
    • När föregås av en icke-citatterad 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 metadiagram som fortfarande behöver undantag.

    • Argumentlägesmetafakter (tecken med särskild syntaktisk betydelse) är: <space> ' " ` , ; ( ) { } | & < > @ # . Av dessa < > @ # är endast särskilda i början av en token.
  • Stop-parsing-token ( --% ) ändrar tolkning av alla återstående argument. Mer information finns i avsnittet stop-parsing token nedan.

Exempel

Följande tabell innehåller flera exempel på token som bearbetas i uttrycks- och argumentläge och utvärderingen av dessa token. I de här exemplen är värdet för $a variabeln 4 .

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 på om PowerShell vet hur argumentet ska konverteras till rätt typ. I följande tabell visas flera exempel på de typer som tilldelats till 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 sammanfogas sedan till en enda sträng där varje parameter avgränsas med ett blanksteg.

Följande kommando anropar till exempel icacls.exe programmet.

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

Stop-parsing-token

Från och med PowerShell 3.0 kan du använda stop-parsing-token ( ) för att hindra PowerShell från att tolka indata --% somPowerShell-kommandon eller uttryck.

Anteckning

Stop-parsing-token är endast avsedd att användas på Windows plattformar.

När du anropar ett inbyggt kommando placerar du token stop-parsing 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 stop-parsing-token behandlar PowerShell återstående tecken på raden som en literal. Den enda tolkning den utför är att ersätta värden för miljövariabler som använder standardvärden Windows notation, till exempel %USERPROFILE% .

icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F

PowerShell skickar följande kommandosträng till icacls.exe programmet:

X:\VMS /grant Dom\HVAdmin:(CI)(OI)F

Stop-parsing-token gäller endast tills nästa nyrad eller pipeline-tecken. Du kan inte använda ett fortsättningstecken ( ) för att utöka dess effekt eller använda en ` kommandoavgränsare ( ; ) för att avsluta dess effekt.

Förutom %variable% miljövariabelreferenser kan du inte bädda in andra dynamiska element i kommandot. Undantag för ett tecken som stöds inte på det sätt som du kan göra % %% i batchfiler. %<name>% token utökas alltid. Om <name> inte refererar till en definierad miljövariabel skickas token via som den är.

Du kan inte använda omdirigering av dataströmmar (till exempel ) eftersom de skickas >file.txt ordagrann 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 det citattecken som du angav. De parsade argumenten sammanfogas sedan till en enda sträng där varje parameter avgränsas med ett blanksteg. Den här strängen tilldelas sedan till egenskapen Arguments för ett ProcessStartInfo objekt. Citattecken i strängen måste vara utom citattecken eller omstreck ( \ ).

Anteckning

Omsnedstrecket ( \ ) 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.

Följande exempel använder TestExe.exe verktyget . Det här verktyget används av Testverktyg i PowerShell-källdatabasen. Målet med de här exemplen är att skicka katalogsökvägen till ett inbyggt kommando "C:\Program Files (x86)\Microsoft\" så att den tog emot sökvägen som en citerad sträng.

Parametern echoargs för TestExe 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 rymt 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 samma för alla exempel:

Arg 0 is <"C:\Program Files (x86)\Microsoft\">

Du kan TestExe skapa från källkoden. Se TestExe.

Se även

about_Command_Syntax