about_Parsing
Korte beschrijving
Beschrijft hoe PowerShell opdrachten parseert.
Lange beschrijving
Wanneer u een opdracht invoert bij de opdrachtprompt, splitst PowerShell de opdrachttekst op in een reeks segmenten die tokens worden genoemd en wordt vervolgens bepaald hoe elk token moet worden geïnterpreteerd.
Als u bijvoorbeeld het volgende typt:
Write-Host book
PowerShell splitst de opdracht op in twee tokens, Write-Host
en book
, en interpreteert elk token onafhankelijk met behulp van een van de twee belangrijkste parseringsmodi: de expressiemodus en de argumentmodus.
Notitie
Terwijl PowerShell opdrachtinvoer parseert, wordt geprobeerd de opdrachtnamen om te lossen naar cmdlets of systeemeigen uitvoerbare bestanden. Als een opdrachtnaam niet exact overeenkomt, wordt de opdracht in PowerShell Get-
als standaardwerkwoord gebruikt. PowerShell parseert Process
bijvoorbeeld als Get-Process
. Het wordt afgeraden om deze functie te gebruiken om de volgende redenen:
- Het is inefficiënt. Dit zorgt ervoor dat PowerShell meerdere keren zoekt.
- Externe programma's met dezelfde naam worden eerst omgezet, dus u kunt de beoogde cmdlet niet uitvoeren.
Get-Help
enGet-Command
herkennen namen die geen werkwoord nodig hebben.
Expressiemodus
De expressiemodus is bedoeld voor het combineren van expressies, die vereist zijn voor het bewerken van waarden in een scripttaal. Expressies zijn weergaven van waarden in PowerShell-syntaxis en kunnen eenvoudig of samengesteld zijn, bijvoorbeeld:
Letterlijke expressies zijn directe weergaven van hun waarden:
'hello'
32
Variabele-expressies dragen de waarde van de variabele waarnaar ze verwijzen:
$x
$script:path
Operators combineren andere expressies voor evaluatie:
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- Letterlijke tekenreeksen moeten tussen aanhalingstekens staan.
- Getallen worden behandeld als numerieke waarden in plaats van als een reeks tekens (tenzij er een escape-teken is).
- Operators, waaronder unaire operators zoals
-
en-not
en binaire operatoren zoals+
en-gt
, worden geïnterpreteerd als operatoren en passen hun respectieve bewerkingen toe op hun argumenten (operanden). - Kenmerk- en conversieexpressies worden geparseerd als expressies en toegepast op onderliggende expressies, bijvoorbeeld
[int] '7'
. - Variabeleverwijzingen worden geëvalueerd naar hun waarden, maar splatting (dat wil zeggen het plakken van vooraf ingevulde parametersets) is verboden en veroorzaakt een parserfout.
- Al het andere wordt behandeld als een opdracht die moet worden aangeroepen.
Argumentmodus
Tijdens het parseren wordt in PowerShell eerst gezocht naar het interpreteren van invoer als een expressie. Maar wanneer er een opdrachtaanroep wordt aangetroffen, wordt het parseren voortgezet in de argumentmodus. Als u argumenten hebt die spaties bevatten, zoals paden, moet u deze argumentwaarden tussen aanhalingstekens plaatsen.
De argumentmodus is ontworpen voor het parseren van argumenten en parameters voor opdrachten in een shell-omgeving. Alle invoer wordt behandeld als een uitbreidbare tekenreeks, tenzij een van de volgende syntaxis wordt gebruikt:
Dollarteken (
$
) gevolgd door een variabelenaam begint een variabelereferentie, anders wordt het geïnterpreteerd als onderdeel van de uitbreidbare tekenreeks. De variabeleverwijzing kan toegang tot leden of indexering omvatten.- Aanvullende tekens na eenvoudige variabeleverwijzingen, zoals
$HOME
, worden beschouwd als onderdeel van hetzelfde argument. Plaats de naam van de variabele tussen accolades ({}
) om deze te scheiden van de volgende tekens. Bijvoorbeeld${HOME}
. - Wanneer de variabelereferentie lidtoegang bevat, wordt de eerste van de extra tekens beschouwd als het begin van een nieuw argument. Resulteert bijvoorbeeld
$HOME.Length-more
in twee argumenten: de waarde van$HOME.Length
en de letterlijke-more
tekenreeks .
- Aanvullende tekens na eenvoudige variabeleverwijzingen, zoals
Aanhalingstekens (
'
en"
) beginnen tekenreeksenAccolades (
{}
) beginnen met nieuwe scriptblokkenKomma's (
,
) introduceren lijsten die worden doorgegeven als matrices, behalve wanneer de aan te roepen opdracht een systeemeigen toepassing is, in welk geval ze worden geïnterpreteerd als onderdeel van de uitbreidbare tekenreeks. Beginkomma's, opeenvolgende komma's of volgkomma's worden niet ondersteund.Haakjes (
()
) beginnen met een nieuwe expressieDe operator Subexpressie (
$()
) begint een ingesloten expressieInitial at sign (
@
) begint met expressiesyntaxis, zoals splatting (@args
), matrices (@(1,2,3)
) en letterlijke hashtabellen (@{a=1;b=2}
).()
,$()
en@()
aan het begin van een token maakt u een nieuwe parseringscontext die expressies of geneste opdrachten kan bevatten.- Wanneer het eerste extra teken wordt gevolgd door extra tekens, wordt dit beschouwd als het begin van een nieuw, afzonderlijk argument.
- Wanneer voorafgegaan door een letterlijke waarde
$()
zonder aanhalingstekens werkt als een uitbreidbare tekenreeks,()
wordt een nieuw argument gestart dat een expressie is en@()
letterlijk@
wordt genomen met()
het starten van een nieuw argument dat een expressie is.
Al het andere wordt behandeld als een uitbreidbare tekenreeks, met uitzondering van metatekens die nog steeds moeten worden gevlucht.
- De metatekens in de argumentmodus (tekens met een speciale syntactische betekenis) zijn:
<space> ' " ` , ; ( ) { } | & < > @ #
.< > @ #
Deze zijn alleen speciaal aan het begin van een token.
- De metatekens in de argumentmodus (tekens met een speciale syntactische betekenis) zijn:
Het token voor stoppen parseren (
--%
) wijzigt de interpretatie van alle resterende argumenten. Zie de sectie stop-parsing token hieronder voor meer informatie.
Voorbeelden
De volgende tabel bevat enkele voorbeelden van tokens die zijn verwerkt in de expressiemodus en argumentmodus en de evaluatie van deze tokens. Voor deze voorbeelden is 4
de waarde van de variabele $a
.
Voorbeeld | Modus | Resultaat |
---|---|---|
2 |
Expression | 2 (geheel getal) |
`2 |
Expression | "2" (opdracht) |
Write-Output 2 |
Expression | 2 (geheel getal) |
2+2 |
Expression | 4 (geheel getal) |
Write-Output 2+2 |
Argument | "2+2" (tekenreeks) |
Write-Output(2+2) |
Expression | 4 (geheel getal) |
$a |
Expression | 4 (geheel getal) |
Write-Output $a |
Expression | 4 (geheel getal) |
$a+2 |
Expression | 6 (geheel getal) |
Write-Output $a+2 |
Argument | "4+2" (tekenreeks) |
$- |
Argument | "$-" (opdracht) |
Write-Output $- |
Argument | "$-" (tekenreeks) |
a$a |
Expression | "a$a" (opdracht) |
Write-Output a$a |
Argument | "a4" (tekenreeks) |
a'$a' |
Expression | "a$a" (opdracht) |
Write-Output a'$a' |
Argument | "a$a" (tekenreeks) |
a"$a" |
Expression | "a$a" (opdracht) |
Write-Output a"$a" |
Argument | "a4" (tekenreeks) |
a$(2) |
Expression | "a$(2)" (opdracht) |
Write-Output a$(2) |
Argument | "a2" (tekenreeks) |
Elk token kan worden geïnterpreteerd als een soort objecttype, zoals Booleaanse waarde of tekenreeks. PowerShell probeert het objecttype van de expressie te bepalen. Het objecttype is afhankelijk van het type parameter dat een opdracht verwacht en of PowerShell weet hoe het argument moet worden geconverteerd naar het juiste type. In de volgende tabel ziet u enkele voorbeelden van de typen die zijn toegewezen aan waarden die door de expressies worden geretourneerd.
Voorbeeld | Modus | Resultaat |
---|---|---|
Write-Output !1 |
Argument | "!1" (tekenreeks) |
Write-Output (!1) |
expressie | Onwaar (Booleaans) |
Write-Output (2) |
expressie | 2 (geheel getal) |
Set-Variable AB A,B |
Argument | 'A','B' (matrix) |
CMD /CECHO A,B |
Argument | 'A,B' (tekenreeks) |
CMD /CECHO $AB |
expressie | 'A B' (matrix) |
CMD /CECHO :$AB |
Argument | ':A B' (tekenreeks) |
Argumenten doorgeven aan systeemeigen opdrachten
Bij het uitvoeren van systeemeigen opdrachten vanuit PowerShell worden de argumenten eerst geparseerd door PowerShell. De geparseerde argumenten worden vervolgens samengevoegd in één tekenreeks waarbij elke parameter wordt gescheiden door een spatie.
Met de volgende opdracht wordt het icacls.exe
programma bijvoorbeeld aangeroepen.
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Als u deze opdracht wilt uitvoeren in PowerShell 2.0, moet u escape-tekens gebruiken om te voorkomen dat PowerShell de haakjes verkeerd interpreteert.
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
Het token voor stoppen met parseren
Vanaf PowerShell 3.0 kunt u het token stoppen-parseren (--%
) gebruiken om te voorkomen dat PowerShell invoer interpreteert als PowerShell-opdrachten of -expressies.
Notitie
Het token voor stoppen met parseren is alleen bedoeld voor gebruik op Windows-platforms.
Wanneer u een systeemeigen opdracht aanroept, plaatst u het stop-parsing-token vóór de programmaargumenten. Deze techniek is veel eenvoudiger dan het gebruik van escape-tekens om onjuiste interpretatie te voorkomen.
Wanneer er een stopparseringstoken wordt aantreft, worden de resterende tekens in de regel door PowerShell als letterlijk behandeld. De enige interpretatie die wordt uitgevoerd, is het vervangen van waarden voor omgevingsvariabelen die gebruikmaken van de standaard Windows-notatie, zoals %USERPROFILE%
.
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
PowerShell verzendt de volgende opdrachtreeks naar het icacls.exe
programma:
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Het stop-parsing-token is alleen geldig tot het volgende nieuwe regel- of pijplijnteken. U kunt een vervolgteken (`
) niet gebruiken om het effect ervan uit te breiden of een opdrachtscheidingsteken (;
) gebruiken om het effect te beëindigen.
%variable%
Behalve verwijzingen naar omgevingsvariabelen kunt u geen andere dynamische elementen insluiten in de opdracht. Het escapen van een %
teken als %%
, zoals u dat in batchbestanden kunt doen, wordt niet ondersteund. %<name>%
tokens worden steevast uitgevouwen. Als <name>
niet naar een gedefinieerde omgevingsvariabele verwijst, wordt het token als zodanig doorgegeven.
U kunt geen stroomomleiding (zoals >file.txt
) gebruiken, omdat ze als argumenten worden doorgegeven aan de doelopdracht.
Argumenten doorgeven die aanhalingstekens bevatten
Sommige systeemeigen opdrachten verwachten argumenten die aanhalingstekens bevatten. Normaal gesproken wordt bij het parseren van de opdrachtregel van PowerShell het aanhalingsteken verwijderd dat u hebt opgegeven. De geparseerde argumenten worden vervolgens samengevoegd in één tekenreeks waarbij elke parameter wordt gescheiden door een spatie. Deze tekenreeks wordt vervolgens toegewezen aan de eigenschap Argumenten van een ProcessStartInfo
object. Aanhalingstekens binnen de tekenreeks moeten worden ge escaped met extra aanhalingstekens of backslashtekens (\
).
Notitie
Het backslashteken (\
) wordt niet herkend als een escape-teken door PowerShell. Dit is het escape-teken dat wordt gebruikt door de onderliggende API voor ProcessStartInfo.Arguments
.
Zie de documentatie voor ProcessStartInfo.Arguments voor meer informatie over de escape-vereisten.
In de volgende voorbeelden wordt het TestExe.exe
hulpprogramma gebruikt. Dit hulpprogramma wordt gebruikt door de Pester-tests in de PowerShell-bronopslagplaats. Het doel van deze voorbeelden is om het mappad "C:\Program Files (x86)\Microsoft\"
door te geven aan een systeemeigen opdracht, zodat het pad als een tekenreeks met aanhalingstekens wordt ontvangen.
De parameter echoargs van TestExe
geeft de ontvangen waarden als argumenten weer voor het uitvoerbare bestand. U kunt dit hulpprogramma gebruiken om te controleren of u de tekens in uw argumenten correct hebt escaped.
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\\""
De uitvoer is hetzelfde voor alle voorbeelden:
Arg 0 is <"C:\Program Files (x86)\Microsoft\">
U kunt bouwen TestExe
op basis van de broncode. Zie TestExe.
Argumenten doorgeven aan PowerShell-opdrachten
Vanaf PowerShell 3.0 kunt u het token einde van parameters (--
) gebruiken om te voorkomen dat PowerShell invoer interpreteert als PowerShell-parameters. Dit is een conventie die is opgegeven in de specificatie POSIX Shell en Utilities.
Het token einde van parameters (--
) geeft aan dat alle volgende argumenten in hun werkelijke vorm moeten worden doorgegeven alsof er dubbele aanhalingstekens om de aanhalingstekens zijn geplaatst. Met behulp van --
kunt u de tekenreeks -InputObject
bijvoorbeeld uitvoeren zonder aanhalingstekens te gebruiken of deze te laten interpreteren als een parameter:
Write-Output -- -InputObject
-InputObject
In tegenstelling tot het token stop-parsing (--%
), kunnen alle waarden na het --
token worden geïnterpreteerd als expressies door PowerShell.
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
Dit gedrag is alleen van toepassing op PowerShell-opdrachten. Als u het --
token gebruikt bij het aanroepen van een externe opdracht, wordt de --
tekenreeks als argument doorgegeven aan die opdracht.
TestExe -echoargs -a -b -- -c
De uitvoer laat zien dat --
als argument wordt doorgegeven aan TestExe
.
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>