about_Parsing
Krótki opis
Opisuje sposób analizowania poleceń programu PowerShell.
Długi opis
Po wprowadzeniu polecenia w wierszu polecenia program PowerShell dzieli tekst polecenia na serię segmentów nazywanych tokenami , a następnie określa, jak interpretować każdy token.
Jeśli na przykład wpiszesz:
Write-Host book
Program PowerShell dzieli polecenie na dwa tokeny Write-Host
i book
interpretuje każdy token niezależnie przy użyciu jednego z dwóch głównych trybów analizowania: trybu wyrażenia i trybu argumentu.
Uwaga
Gdy program PowerShell analizuje dane wejściowe polecenia, próbuje rozpoznać nazwy poleceń cmdlet lub natywnych plików wykonywalnych. Jeśli nazwa polecenia nie ma dokładnego dopasowania, program PowerShell poprzedza Get-
polecenie jako czasownik domyślny. Na przykład program PowerShell analizuje Process
jako Get-Process
. Nie zaleca się używania tej funkcji z następujących powodów:
- To nieefektywne. Powoduje to wielokrotne wyszukiwanie w programie PowerShell.
- Programy zewnętrzne o tej samej nazwie są rozpoznawane jako pierwsze, więc nie można wykonać zamierzonego polecenia cmdlet.
Get-Help
iGet-Command
nie rozpoznaje nazw bez czasowników.
Tryb wyrażeń
Tryb wyrażeń jest przeznaczony do łączenia wyrażeń wymaganych do manipulowania wartością w języku skryptowym. Wyrażenia są reprezentacjami wartości w składni programu PowerShell i mogą być proste lub złożone, na przykład:
Wyrażenia literału są bezpośrednimi reprezentacjami ich wartości:
'hello'
32
Wyrażenia zmiennych przenoszą wartość zmiennej, do której się odwołują:
$x
$script:path
Operatory łączą inne wyrażenia do oceny:
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- Literały ciągu znaków muszą być zawarte w cudzysłowie.
- Liczby są traktowane jako wartości liczbowe, a nie jako seria znaków (chyba że unikniesz).
- Operatory, w tym operatory jednoargumentowe, takie jak
-
+
-gt
i-not
i binarne, są interpretowane jako operatory i stosują odpowiednie operacje na ich argumentach (operandy). - Wyrażenia atrybutów i konwersji są analizowane jako wyrażenia i stosowane do wyrażeń podrzędnych, np.
[int] '7'
. - Odwołania do zmiennych są oceniane na ich wartości, ale splatting (tj. wklejanie wstępnie wypełnianych zestawów parametrów) jest zabronione i powoduje błąd analizatora.
- Wszystkie inne elementy będą traktowane jako polecenie do wywołania.
Tryb argumentu
Podczas analizowania program PowerShell najpierw analizuje dane wejściowe jako wyrażenie. Jednak po napotkaniu wywołania polecenia analizowanie będzie kontynuowane w trybie argumentu. Jeśli masz argumenty zawierające spacje, takie jak ścieżki, musisz ująć te wartości argumentów w cudzysłowie.
Tryb argumentu jest przeznaczony do analizowania argumentów i parametrów dla poleceń w środowisku powłoki. Wszystkie dane wejściowe są traktowane jako ciąg rozszerzalny, chyba że używa jednej z następujących składni:
Znak dolara (
$
) po nazwie zmiennej rozpoczyna odwołanie do zmiennej, w przeciwnym razie jest interpretowany jako część ciągu rozszerzalnego. Odwołanie do zmiennej może obejmować dostęp do składowych lub indeksowanie.- Dodatkowe znaki po prostych odwołaniach do zmiennych, takich jak
$HOME
, są traktowane jako część tego samego argumentu. Dołącz nazwę zmiennej w nawiasach klamrowych ({}
), aby oddzielić ją od kolejnych znaków. Na przykład${HOME}
. - Gdy odwołanie do zmiennej obejmuje dostęp do elementu członkowskiego, pierwszy z dodatkowych znaków jest uważany za początek nowego argumentu. Na przykład
$HOME.Length-more
wyniki w dwóch argumentach: wartość$HOME.Length
literału-more
ciągu i .
- Dodatkowe znaki po prostych odwołaniach do zmiennych, takich jak
Znaki cudzysłowu (
'
i"
) — ciągi rozpoczynające sięNawiasy klamrowe (
{}
) rozpoczynają nowe bloki skryptówPrzecinki (
,
) wprowadzają listy przekazywane jako tablice, z wyjątkiem sytuacji, gdy polecenie do wywołania jest aplikacją natywną, w tym przypadku są interpretowane jako część ciągu rozszerzalnego. Początkowe, kolejne lub końcowe przecinki nie są obsługiwane.Nawiasy (
()
) rozpoczynają nowe wyrażenieOperator subexpression (
$()
) rozpoczyna wyrażenie osadzoneZnak początkowy (
@
) rozpoczyna składnie wyrażeń, takie jak splatting (@args
), tablice (@(1,2,3)
) i literały tabeli skrótu (@{a=1;b=2}
).()
,$()
i@()
na początku tokenu utwórz nowy kontekst analizowania, który może zawierać wyrażenia lub zagnieżdżone polecenia.- Po kolejnych znakach pierwszy dodatkowy znak jest uznawany za początek nowego, oddzielnego argumentu.
- Gdy poprzedzony niekwestionowanym literałem
$()
działa jak ciąg rozszerzalny,()
uruchamia nowy argument, który jest wyrażeniem i@()
jest przyjmowany jako literał@
()
z uruchomieniem nowego argumentu, który jest wyrażeniem.
Wszystkie inne elementy są traktowane jako ciąg rozszerzalny, z wyjątkiem metacharacters, które nadal wymagają ucieczki.
- Metacharactery trybu argumentów (znaki o specjalnym znaczeniu składniowym) to:
<space> ' " ` , ; ( ) { } | & < > @ #
. Z nich< > @ #
są specjalne tylko na początku tokenu.
- Metacharactery trybu argumentów (znaki o specjalnym znaczeniu składniowym) to:
Token zatrzymania analizowania (
--%
) zmienia interpretację wszystkich pozostałych argumentów. Aby uzyskać więcej informacji, zobacz sekcję tokenu zatrzymywania analizowania poniżej.
Przykłady
Poniższa tabela zawiera kilka przykładów tokenów przetworzonych w trybie wyrażeń i trybie argumentu oraz ocenie tych tokenów. W tych przykładach wartość zmiennej $a
to 4
.
Przykład | Mode | Wynik |
---|---|---|
2 |
Wyrażenie | 2 (liczba całkowita) |
`2 |
Wyrażenie | "2" (polecenie) |
Write-Output 2 |
Wyrażenie | 2 (liczba całkowita) |
2+2 |
Wyrażenie | 4 (liczba całkowita) |
Write-Output 2+2 |
Argument | "2+2" (ciąg) |
Write-Output(2+2) |
Wyrażenie | 4 (liczba całkowita) |
$a |
Wyrażenie | 4 (liczba całkowita) |
Write-Output $a |
Wyrażenie | 4 (liczba całkowita) |
$a+2 |
Wyrażenie | 6 (liczba całkowita) |
Write-Output $a+2 |
Argument | "4+2" (ciąg) |
$- |
Argument | "$-" (polecenie) |
Write-Output $- |
Argument | "$-" (ciąg) |
a$a |
Wyrażenie | "a$a" (polecenie) |
Write-Output a$a |
Argument | "a4" (ciąg) |
a'$a' |
Wyrażenie | "a$a" (polecenie) |
Write-Output a'$a' |
Argument | "a$a" (ciąg) |
a"$a" |
Wyrażenie | "a$a" (polecenie) |
Write-Output a"$a" |
Argument | "a4" (ciąg) |
a$(2) |
Wyrażenie | "a$(2)" (polecenie) |
Write-Output a$(2) |
Argument | "a2" (ciąg) |
Każdy token może być interpretowany jako jakiś typ obiektu, taki jak wartość logiczna lub ciąg. Program PowerShell próbuje określić typ obiektu z wyrażenia. Typ obiektu zależy od typu parametru oczekiwanego przez polecenie i od tego, czy program PowerShell wie, jak przekonwertować argument na poprawny typ. W poniższej tabeli przedstawiono kilka przykładów typów przypisanych do wartości zwracanych przez wyrażenia.
Przykład | Mode | Wynik |
---|---|---|
Write-Output !1 |
Argument | "!1" (ciąg) |
Write-Output (!1) |
expression | False (wartość logiczna) |
Write-Output (2) |
expression | 2 (liczba całkowita) |
Set-Variable AB A,B |
Argument | "A", "B" (tablica) |
CMD /CECHO A,B |
Argument | "A,B" (ciąg) |
CMD /CECHO $AB |
expression | "A B" (tablica) |
CMD /CECHO :$AB |
Argument | ':A B' (ciąg) |
Przekazywanie argumentów do poleceń natywnych
Podczas uruchamiania poleceń natywnych z poziomu programu PowerShell argumenty są najpierw analizowane przez program PowerShell. Przeanalizowane argumenty są następnie łączone w jeden ciąg z każdym parametrem oddzielonym spacją.
Na przykład następujące polecenie wywołuje icacls.exe
program.
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Aby uruchomić to polecenie w programie PowerShell 2.0, należy użyć znaków ucieczki, aby zapobiec błędnej interpretacji nawiasów w programie PowerShell.
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
Token zatrzymania analizy
Począwszy od programu PowerShell 3.0, można użyć tokenu stop-parsing (--%
), aby uniemożliwić programowi PowerShell interpretowanie danych wejściowych jako poleceń lub wyrażeń programu PowerShell.
Uwaga
Token zatrzymania analizy jest przeznaczony tylko do użycia na platformach Windows.
Podczas wywoływania natywnego polecenia umieść token stop-parsing przed argumentami programu. Ta technika jest znacznie łatwiejsza niż używanie znaków ucieczki, aby zapobiec błędnej interpretacji.
W przypadku napotkania tokenu zatrzymania analizowania program PowerShell traktuje pozostałe znaki w wierszu jako literał. Jedyną interpretacją, którą wykonuje, jest zastąpienie wartości zmiennych środowiskowych, które używają standardowej notacji systemu Windows, takiej jak %USERPROFILE%
.
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
Program PowerShell wysyła do programu następujący ciąg icacls.exe
polecenia:
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Token zatrzymania analizy jest skuteczny tylko do następnego nowego wiersza lub znaku potoku. Nie można użyć znaku kontynuacji (`
), aby rozszerzyć jego efekt lub użyć ogranicznika polecenia () w;
celu zakończenia jego efektu.
%variable%
Poza odwołaniami do zmiennych środowiskowych nie można osadzić żadnych innych elementów dynamicznych w poleceniu . Ucieczka znaku jako %%
, sposób, w jaki można zrobić wewnątrz plików wsadowych%
, nie jest obsługiwana. %<name>%
tokeny są niezmiennie rozwinięte. Jeśli <name>
nie odwołuje się do zdefiniowanej zmiennej środowiskowej, token jest przekazywany zgodnie z rzeczywistym użyciem.
Nie można użyć przekierowania strumienia (na przykład >file.txt
), ponieważ są przekazywane dosłownie jako argumenty do polecenia docelowego.
Przekazywanie argumentów zawierających znaki cudzysłowu
Niektóre polecenia natywne oczekują argumentów zawierających znaki cudzysłowu. Zwykle analizowanie wiersza polecenia programu PowerShell powoduje usunięcie podanego znaku cudzysłowu. Przeanalizowane argumenty są następnie łączone w jeden ciąg z każdym parametrem oddzielonym spacją. Ten ciąg jest następnie przypisywany do właściwości ProcessStartInfo
Arguments obiektu. Cudzysłowy w ciągu muszą być znakami ucieczki przy użyciu dodatkowych cudzysłowów lub ukośnika odwrotnego (\
).
Uwaga
Znak ukośnika odwrotnego (\
) nie jest rozpoznawany jako znak ucieczki przez program PowerShell. Jest to znak ucieczki używany przez podstawowy interfejs API dla programu ProcessStartInfo.Arguments
.
Aby uzyskać więcej informacji na temat wymagań dotyczących ucieczki, zobacz dokumentację elementu ProcessStartInfo.Arguments.
W poniższych przykładach użyto TestExe.exe
narzędzia . To narzędzie jest używane przez testy Pester w repozytorium źródłowym programu PowerShell. Celem tych przykładów jest przekazanie ścieżki "C:\Program Files (x86)\Microsoft\"
katalogu do natywnego polecenia, tak aby odebrał ścieżkę jako ciąg cytowany.
Echoargs parametr TestExe
wyświetla wartości odebrane jako argumenty do pliku wykonywalnego. To narzędzie służy do sprawdzania, czy znaki w argumentach zostały prawidłowo zmienione.
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\\""
Dane wyjściowe są takie same dla wszystkich przykładów:
Arg 0 is <"C:\Program Files (x86)\Microsoft\">
Możesz utworzyć TestExe
na podstawie kodu źródłowego. Zobacz TestExe.
Przekazywanie argumentów do poleceń programu PowerShell
Począwszy od programu PowerShell 3.0, można użyć tokenu końca parametrów (--
), aby uniemożliwić programowi PowerShell interpretowanie danych wejściowych jako parametrów programu PowerShell. Jest to konwencja określona w specyfikacji powłoki POSIX i narzędzi.
Token końca parametrów (--
) wskazuje, że wszystkie argumenty następujące po nim mają być przekazywane w ich rzeczywistej formie, jakby cudzysłowy zostały umieszczone wokół nich. Na przykład przy użyciu --
polecenia można wyświetlić ciąg -InputObject
bez użycia cudzysłowów lub interpretowania go jako parametru:
Write-Output -- -InputObject
-InputObject
W przeciwieństwie do tokenu stop-parsing (--%
), wszelkie wartości następujące po tokenie --
mogą być interpretowane jako wyrażenia za pomocą programu PowerShell.
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
To zachowanie dotyczy tylko poleceń programu PowerShell. Jeśli używasz tokenu --
podczas wywoływania polecenia zewnętrznego, --
ciąg jest przekazywany jako argument do tego polecenia.
TestExe -echoargs -a -b -- -c
Dane wyjściowe pokazują, że --
element jest przekazywany jako argument do elementu TestExe
.
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>