about_Parsing
간단한 설명
PowerShell에서 명령을 구문 분석하는 방법을 설명합니다.
자세한 설명
명령 프롬프트에 명령을 입력하면 PowerShell은 명령 텍스트를 토큰이라는 일련의 세그먼트로 나눕니다. 그런 다음 각 토큰을 해석하는 방법을 결정합니다.
예를 들어 다음을 입력하는 경우
Write-Host book
PowerShell은 명령을 두 개의 토큰 Write-Host
으로 분할하고 식 모드 및 book
인수 모드의 두 가지 주요 구문 분석 모드 중 하나를 사용하여 각 토큰을 독립적으로 해석합니다.
참고 항목
PowerShell은 명령 입력을 구문 분석할 때 명령 이름을 cmdlet 또는 네이티브 실행 파일로 확인하려고 시도합니다. 명령 이름에 정확히 일치하는 항목이 없으면 PowerShell이 명령 앞에 기본 동사로 추가됩니다 Get-
. 예를 들어 PowerShell은 .로 Get-Service
구문 분석합니다Service
. 다음과 같은 이유로 이 기능을 사용하지 않는 것이 좋습니다.
- 비효율적입니다. 이렇게 하면 PowerShell이 여러 번 검색됩니다.
- 이름이 같은 외부 프로그램이 먼저 확인되므로 의도한 cmdlet을 실행할 수 없습니다.
Get-Help
동Get-Command
사 없는 이름을 인식하지 않습니다.- 명령 이름은 예약어 또는 언어 키워드일 수 있습니다.
Process
은 둘 다이며 확인할 수Get-Process
없습니다.
식 모드
식 모드는 스크립팅 언어의 값 조작에 필요한 식을 결합하기 위한 것입니다. 식은 PowerShell 구문의 값 표현이며 단순하거나 복합적일 수 있습니다. 예를 들면 다음과 같습니다.
리터럴 식은 해당 값의 직접 표현입니다.
'hello'
32
변수 식은 참조하는 변수의 값을 전달합니다.
$x
$script:path
연산자는 평가를 위해 다른 식을 결합합니다.
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- 문자열 리터럴은 따옴표로 묶어야 합니다.
- 숫자는 일련의 문자가 아닌 숫자 값으로 처리됩니다(이스케이프되지 않는 한).
- 단항 연산자 및 이진 연산자 등
-
-not
과 같은+
-gt
연산자는 연산자로 해석되고 해당 인수(피연산자)에 해당 연산을 적용합니다. - 특성 및 변환 식은 식으로 구문 분석되고 하위 식에 적용됩니다. 예:
[int] '7'
- 변수 참조는 해당 값으로 평가되지만 스플래팅 은 금지되어 파서 오류가 발생합니다.
- 다른 항목은 호출할 명령으로 처리됩니다.
인수 모드
구문 분석할 때 PowerShell은 먼저 입력을 식으로 해석하려고 합니다. 그러나 명령 호출이 발생하면 인수 모드에서 구문 분석이 계속됩니다. 경로와 같은 공백이 포함된 인수가 있는 경우 해당 인수 값을 따옴표로 묶어야 합니다.
인수 모드는 셸 환경에서 명령에 대한 인수 및 매개 변수를 구문 분석하기 위해 설계되었습니다. 다음 구문 중 하나를 사용하지 않는 한 모든 입력은 확장 가능한 문자열로 처리됩니다.
달러 기호(
$
)와 변수 이름이 뒤에 오면 변수 참조가 시작되고, 그렇지 않으면 확장 가능한 문자열의 일부로 해석됩니다. 변수 참조에는 멤버 액세스 또는 인덱싱이 포함될 수 있습니다.- 같은 간단한 변수 참조를
$HOME
따르는 추가 문자는 동일한 인수의 일부로 간주됩니다. 변수 이름을 중괄호({}
)로 묶어 후속 문자와 구분합니다. 예들 들어${HOME}
입니다. - 변수 참조에 멤버 액세스가 포함된 경우 추가 문자 중 첫 번째 문자는 새 인수의 시작으로 간주됩니다. 예를 들어
$HOME.Length-more
두 개의 인수인 값과 문자열 리터럴이$HOME.Length
생성됩니다-more
.
- 같은 간단한 변수 참조를
따옴표(
'
및"
) 시작 문자열중괄호(
{}
)가 새 스크립트 블록을 시작합니다.호출되는 명령이 네이티브 애플리케이션이 아닌 한 쉼표(
,
)는 배열로 전달된 목록을 도입합니다. 이 경우 확장 가능한 문자열의 일부로 해석됩니다. 초기, 연속 또는 후행 쉼표는 지원되지 않습니다.괄호(
()
)가 새 식을 시작합니다.하위 식 연산자(
$()
)가 포함된 식을 시작합니다.초기 기호(
@
)는 스플래팅(), 배열(@args
) 및 해시 테이블 리터럴(@(1,2,3)
@{a=1;b=2}
)과 같은 식 구문을 시작합니다.()
,$()
및@()
토큰의 시작 부분에 식 또는 중첩된 명령을 포함할 수 있는 새 구문 분석 컨텍스트를 만듭니다.- 뒤에 추가 문자가 추가되면 첫 번째 추가 문자는 별도의 새 인수의 시작으로 간주됩니다.
- 앞에 따옴표가 없는 리터럴
$()
이 확장 가능한 문자열()
처럼 작동하면 식인 새 인수를 시작하고 식@()
인 새 인수를 시작하여 리터럴@
()
로 사용합니다.
이스케이프가 여전히 필요한 메타 문자는 제외하고 다른 모든 항목은 확장 가능한 문자열로 처리됩니다. 특수 문자 처리를 참조 하세요.
- 인수 모드 메타 문자(특수 구문 의미가 있는 문자)는 다음과
<space> ' " ` , ; ( ) { } | & < > @ #
같습니다. 이< > @ #
중 토큰이 시작될 때만 특별합니다.
- 인수 모드 메타 문자(특수 구문 의미가 있는 문자)는 다음과
중지 구문 분석 토큰(
--%
)은 나머지 모든 인수의 해석을 변경합니다. 자세한 내용은 아래의 토큰 구문 분석 중지 섹션을 참조하세요.
예제
다음 표에서는 식 모드 및 인수 모드에서 처리되는 토큰과 해당 토큰의 평가에 대한 몇 가지 예제를 제공합니다. 이러한 예제의 경우 변수 $a
값은 .입니다 4
.
예시 | 모드 | 결과 |
---|---|---|
2 |
식 | 2(정수) |
`2 |
식 | "2"(명령) |
Write-Output 2 |
식 | 2(정수) |
2+2 |
식 | 4(정수) |
Write-Output 2+2 |
인수 | "2+2"(문자열) |
Write-Output(2+2) |
식 | 4(정수) |
$a |
식 | 4(정수) |
Write-Output $a |
식 | 4(정수) |
$a+2 |
식 | 6(정수) |
Write-Output $a+2 |
인수 | "4+2"(문자열) |
$- |
인수 | "$-"(명령) |
Write-Output $- |
인수 | "$-"(문자열) |
a$a |
식 | "a$a"(명령) |
Write-Output a$a |
인수 | "a4"(문자열) |
a'$a' |
식 | "a$a"(명령) |
Write-Output a'$a' |
인수 | "a$a"(문자열) |
a"$a" |
식 | "a$a"(명령) |
Write-Output a"$a" |
인수 | "a4"(문자열) |
a$(2) |
식 | "a$(2)"(명령) |
Write-Output a$(2) |
인수 | "a2"(문자열) |
모든 토큰은 부울 또는 문자열과 같은 일종의 개체 형식으로 해석될 수 있습니다. PowerShell은 식에서 개체 형식을 확인하려고 시도합니다. 개체 형식은 명령이 예상하는 매개 변수의 형식과 PowerShell에서 인수를 올바른 형식으로 변환하는 방법을 알고 있는지에 따라 달라집니다. 다음 표에서는 식에서 반환된 값에 할당된 형식의 몇 가지 예를 보여 줍니다.
예시 | 모드 | 결과 |
---|---|---|
Write-Output !1 |
argument | "!1"(문자열) |
Write-Output (!1) |
식 | False(부울) |
Write-Output (2) |
식 | 2(정수) |
Set-Variable AB A,B |
argument | 'A','B'(배열) |
CMD /CECHO A,B |
argument | 'A,B'(문자열) |
CMD /CECHO $AB |
식 | 'A B'(배열) |
CMD /CECHO :$AB |
argument | ':A B'(문자열) |
특수 문자 처리
백틱 문자(`
)는 식의 특수 문자를 이스케이프하는 데 사용할 수 있습니다. 메타문자가 아닌 리터럴 문자로 사용하려는 인수 모드 메타문자를 이스케이프하는 데 가장 유용합니다. 예를 들어 달러 기호($
)를 확장 가능한 문자열에서 리터럴로 사용하려면 다음을 수행합니다.
"The value of `$ErrorActionPreference is '$ErrorActionPreference'."
The value of $ErrorActionPreference is 'Continue'.
줄 연속
다음 줄에서 입력을 계속할 수 있도록 줄 끝에 백틱 문자를 사용할 수도 있습니다. 이렇게 하면 이름 및 인수 값이 긴 여러 매개 변수를 사용하는 명령의 가독성이 향상됩니다. 예시:
New-AzVm `
-ResourceGroupName "myResourceGroupVM" `
-Name "myVM" `
-Location "EastUS" `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNetworkSecurityGroup" `
-PublicIpAddressName "myPublicIpAddress" `
-Credential $cred
그러나 줄 연속을 사용하지 않아야 합니다.
- 백틱 문자는 보기 어렵고 잊기 쉬울 수 있습니다.
- 백틱 후 추가 공간이 줄 연속을 중단합니다. 공간을 확인하기 어렵기 때문에 오류를 찾기 어려울 수 있습니다.
PowerShell은 구문의 자연점에서 여러 가지 방법으로 줄 바꿈을 제공합니다.
- 후 파이프 문자(
|
) - 이진 연산자 후(
+
,-
,-eq
등) - 배열의 후 쉼표(
,
) - 와 같은
[
{
문자를 연 후(
큰 매개 변수 집합의 경우 스플래팅을 대신 사용합니다. 예시:
$parameters = @{
ResourceGroupName = "myResourceGroupVM"
Name = "myVM"
Location = "EastUS"
VirtualNetworkName = "myVnet"
SubnetName = "mySubnet"
SecurityGroupName = "myNetworkSecurityGroup"
PublicIpAddressName = "myPublicIpAddress"
Credential = $cred
}
New-AzVm @parameters
네이티브 명령에 인수 전달
PowerShell에서 네이티브 명령을 실행할 때 인수는 먼저 PowerShell에서 구문 분석됩니다. 구문 분석된 인수는 각 매개 변수를 공백으로 구분하여 단일 문자열로 조인합니다.
예를 들어 다음 명령은 프로그램을 호출합니다 icacls.exe
.
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
PowerShell 2.0에서 이 명령을 실행하려면 이스케이프 문자를 사용하여 PowerShell이 괄호를 잘못 해석하지 못하도록 해야 합니다.
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
중지 구문 분석 토큰
PowerShell 3.0부터는 중지 구문 분석(--%
) 토큰을 사용하여 PowerShell이 PowerShell 명령 또는 식으로 입력을 해석하지 못하도록 할 수 있습니다.
참고 항목
중지 구문 분석 토큰은 Windows 플랫폼에서 네이티브 명령을 사용하기 위한 것입니다.
네이티브 명령을 호출할 때 프로그램 인수 앞에 중지 구문 분석 토큰을 배치합니다. 이 기술은 잘못된 해석을 방지하기 위해 이스케이프 문자를 사용하는 것보다 훨씬 쉽습니다.
중지 구문 분석 토큰이 발견되면 PowerShell은 줄의 나머지 문자를 리터럴로 처리합니다. 이 함수가 수행하는 유일한 해석은 표준 Windows 표기법을 사용하는 환경 변수의 값(예: %USERPROFILE%
.)을 대체하는 것입니다.
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
PowerShell은 다음 명령 문자열을 icacls.exe
프로그램에 보냅니다.
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
중지 구문 분석 토큰은 다음 줄 바꿈 또는 파이프라인 문자까지만 유효합니다. 줄 연속 문자(`
)를 사용하여 효과를 확장하거나 명령 구분 기호(;
)를 사용하여 효과를 종료할 수 없습니다.
%variable%
환경 변수 참조 외에는 명령에 다른 동적 요소를 포함할 수 없습니다. %
일괄 처리 파일 내에서 수행할 수 있는 방법으로 문자를 %%
이스케이프하는 것은 지원되지 않습니다. %<name>%
토큰은 변함없이 확장됩니다. <name>
정의된 환경 변수를 참조하지 않으면 토큰이 있는 그대로 전달됩니다.
스트림 리디렉션은 대상 명령에 인수로 축자로 전달되므로(예: >file.txt
) 사용할 수 없습니다.
다음 예제에서 첫 번째 단계는 중지 구문 분석 토큰을 사용하지 않고 명령을 실행합니다. PowerShell은 따옴표 붙은 문자열을 평가하고 값(따옴표 없음)을 전달하여 cmd.exe
오류가 발생합니다.
PS> cmd /c echo "a|b"
'b' is not recognized as an internal or external command,
operable program or batch file.
PS> cmd /c --% echo "a|b"
"a|b"
참고 항목
PowerShell cmdlet을 사용할 때는 중지 구문 분석 토큰이 필요하지 않습니다. 그러나 이러한 인수를 사용하여 네이티브 명령을 호출하도록 설계된 PowerShell 함수에 인수를 전달하는 것이 유용할 수 있습니다.
따옴표 문자가 포함된 인수 전달
일부 네이티브 명령에는 따옴표 문자가 포함된 인수가 사용됩니다. PowerShell 7.3은 명령줄이 네이티브 명령에 대해 구문 분석되는 방식을 변경했습니다.
주의
새 동작은 Windows PowerShell 5.1 동작의 호환성이 손상되는 변경 입니다. 새로운 동작은 네이티브 애플리케이션을 호출할 때 발생하는 다양한 문제를 해결하는 스크립트와 자동화를 손상할 수 있습니다. 필요할 때 네이티브 인수 전달을 방지하려면 중지 구문 분석 토큰(--%
) 또는 Start-Process
cmdlet을 사용합니다.
새 $PSNativeCommandArgumentPassing
기본 설정 변수는 이 동작을 제어합니다. 이 변수를 사용하면 런타임에 동작을 선택할 수 있습니다. 유효한 값은 Legacy
, Standard
및 Windows
. 기본 동작은 플랫폼별로 다릅니다. Windows 플랫폼에서는 기본 설정이고 Windows 플랫폼이 아닌 플랫폼은 기본값입니다 Windows
Standard
.
Legacy
는 역사적인 동작입니다. 모드에서는 Windows
다음 파일의 Windows
호출에서 자동으로 스타일 인수 전달을 사용하는 경우를 제외하고 모드의 동작과 Standard
모드는 Legacy
동일합니다.
cmd.exe
cscript.exe
wscript.exe
.bat
로 끝남.cmd
로 끝남.js
로 끝남.vbs
로 끝남.wsf
로 끝남
둘 $PSNativeCommandArgumentPassing
중 하나 Legacy
또는 Standard
로 설정된 경우 파서는 이러한 파일을 확인하지 않습니다.
참고 항목
다음 예제에서는 도구를 사용합니다 TestExe.exe
. 소스 코드에서 빌드 TestExe
할 수 있습니다. PowerShell 원본 리포지토리에서 TestExe를 참조하세요.
이 변경으로 사용할 수 있는 새 동작:
따옴표가 포함된 리터럴 또는 확장 가능한 문자열은 이제 다음과 같이 유지됩니다.
PS> $a = 'a" "b' PS> TestExe -echoargs $a 'c" "d' e" "f Arg 0 is <a" "b> Arg 1 is <c" "d> Arg 2 is <e f>
인수로 사용되는 빈 문자열은 이제 유지됩니다.
PS> TestExe -echoargs '' a b '' Arg 0 is <> Arg 1 is <a> Arg 2 is <b> Arg 3 is <>
이러한 예제의 목표는 디렉터리 경로(공백 및 따옴표 포함) "C:\Program Files (x86)\Microsoft\"
를 네이티브 명령에 전달하여 경로를 따옴표 붙은 문자열로 수신하는 것입니다.
또는 Standard
모드에서 Windows
다음 예제는 예상된 결과를 생성합니다.
TestExe -echoargs """${env:ProgramFiles(x86)}\Microsoft\"""
TestExe -echoargs '"C:\Program Files (x86)\Microsoft\"'
모드에서 Legacy
동일한 결과를 얻으려면 따옴표를 이스케이프하거나 중지 구문 분석 토큰()--%
을 사용해야 합니다.
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 --% """%ProgramFiles(x86)%\Microsoft\\""
참고 항목
백슬래시(\
) 문자는 PowerShell에서 이스케이프 문자로 인식되지 않습니다. ProcessStartInfo.ArgumentList의 기본 API 에서 사용하는 이스케이프 문자입니다.
PowerShell 7.3에는 네이티브 명령에 대한 매개 변수 바인딩을 추적하는 기능도 추가되었습니다. 자세한 내용은 Trace-Command를 참조 하세요.
PowerShell 명령에 인수 전달
PowerShell 3.0부터 매개 변수 끝 토큰(--
)을 사용하여 PowerShell이 입력을 PowerShell 매개 변수로 해석하지 못하도록 할 수 있습니다. POSIX 셸 및 유틸리티 사양에 지정된 규칙입니다.
매개 변수 끝 토큰
매개 변수 끝 토큰(--
)은 다음에 있는 모든 인수가 큰따옴표가 있는 것처럼 실제 형식으로 전달되어야 임을 나타냅니다. 예를 들어 따옴표를 사용 --
하거나 매개 변수로 해석하지 않고 문자열 -InputObject
을 출력할 수 있습니다.
Write-Output -- -InputObject
-InputObject
중지 구문 분석(--%
) 토큰과 달리 토큰 다음의 --
모든 값은 PowerShell에서 식으로 해석될 수 있습니다.
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
이 동작은 PowerShell 명령에만 적용됩니다. 외부 명령을 --
호출할 때 토큰을 사용하는 --
경우 문자열은 해당 명령에 인수로 전달됩니다.
TestExe -echoargs -a -b -- -c
출력은 인수로 TestExe
전달되는 것을 --
보여줍니다.
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>
Tilde (~)
타일드 문자(~
)는 PowerShell에서 특별한 의미를 줍니다. 경로의 시작 부분에서 PowerShell 명령과 함께 사용되는 경우 타일 문자가 사용자의 홈 디렉터리로 확장됩니다. 타일드 문자가 경로의 다른 곳에서 사용되는 경우 리터럴 문자로 처리됩니다.
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Set-Location ~
PS C:\Users\user2> $PWD
Path
----
C:\Users\user2
이 예제 에서는 Name 매개 변수에 New-Item
문자열이 필요합니다. 타일드 문자는 리터럴 문자로 처리됩니다. 새로 만든 디렉터리로 변경하려면 경로를 타일드 문자로 한정해야 합니다.
PS D:\temp> Set-Location ~
PS C:\Users\user2> New-Item -Type Directory -Name ~
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/6/2024 2:08 PM ~
PS C:\Users\user2> Set-Location ~
PS C:\Users\user2> Set-Location .\~
PS C:\Users\user2\~> $PWD
Path
----
C:\Users\user2\~
네이티브 명령과 함께 타일드 문자를 사용하는 경우 PowerShell은 타일을 리터럴 문자로 전달합니다. 경로에 타일을 사용하면 타일 문자를 지원하지 않는 Windows의 네이티브 명령에 오류가 발생합니다.
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Get-Item ~\repocache.clixml
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/29/2024 3:42 PM 88177 repocache.clixml
PS D:\temp> more.com ~\repocache.clixml
Cannot access file D:\temp\~\repocache.clixml
참고 항목
PowerShell