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 bookinterpretuje 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 i Get-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 -+-gti -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 -moreciągu i .
  • Znaki cudzysłowu (' i ") — ciągi rozpoczynające się

  • Nawiasy klamrowe ({}) rozpoczynają nowe bloki skryptów

  • Przecinki (,) 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żenie

  • Operator subexpression ($()) rozpoczyna wyrażenie osadzone

  • Znak 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.
  • 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>

Zobacz też