다음을 통해 공유


파싱에 관한

간단한 설명

PowerShell에서 명령을 구문 분석하는 방법을 설명합니다.

긴 설명

명령 프롬프트에서 명령을 입력하면 PowerShell은 명령 텍스트를 토큰이라는 일련의 세그먼트로 나눕니다. 그런 다음 각 토큰을 해석하는 방법을 결정합니다.

예를 들어 다음을 입력하는 경우

Write-Host book

PowerShell은 명령을 Write-Hostbook두 개의 토큰으로 분할하고 식 모드 및 인수 모드의 두 가지 주요 구문 분석 모드 중 하나를 사용하여 각 토큰을 독립적으로 해석합니다.

비고

PowerShell은 명령 입력을 구문 분석할 때 명령 이름을 cmdlet 또는 네이티브 실행 파일로 확인하려고 시도합니다. 명령 이름에 정확히 일치하는 항목이 없는 경우 PowerShell은 명령 앞에 기본 동사로 추가합니다 Get- . 예를 들어 PowerShell은 ProcessGet-Process로 구문 분석합니다. 다음과 같은 이유로 이 기능을 사용하지 않는 것이 좋습니다.

  • 비효율적입니다. 이렇게 하면 PowerShell이 여러 차례 검색을 수행하게 됩니다.
  • 이름이 같은 외부 프로그램이 먼저 확인되므로 의도한 cmdlet을 실행하지 못할 수 있습니다.
  • Get-HelpGet-Command 동사 없는 이름을 인식하지 않습니다.

수식 모드

식 모드는 스크립팅 언어의 값 조작에 필요한 식을 결합하기 위한 것입니다. 식은 PowerShell 구문의 값 표현이며 단순하거나 복합적일 수 있습니다. 예를 들면 다음과 같습니다.

리터럴 식은 해당 값의 직접 표현입니다.

'hello'
32

변수 식은 참조하는 변수의 값을 전달합니다.

$x
$script:path

연산자는 평가를 위해 다른 식을 결합합니다.

-12
-not $Quiet
3 + 7
$input.Length -gt 1
  • 문자열 리터럴 따옴표에 포함되어야 합니다.
  • 숫자는 이스케이프되지 않는 한 문자 시퀀스가 아닌 숫자 값으로 처리됩니다.
  • - 같은 단항 연산자 및 -not+같은 이진 연산자를 포함한 -gt연산자로 해석되고 해당 인수(피연산자)에 해당 연산자를 적용합니다.
  • Attribute 및 conversion 표현식 은 표현식으로 구문 분석되고 종속 표현식에 적용됩니다(예 [int] '7': .
  • 변수 참조 는 해당 값으로 평가되지만 스플래팅 (즉, 미리 채워진 매개 변수 집합 붙여넣기)은 금지되며 파서 오류가 발생합니다.
  • 다른 모든 것은 호출할 명령으로 처리됩니다.

인수 모드

구문 분석할 때 PowerShell은 먼저 입력을 식으로 해석합니다. 그러나 명령 호출이 발생하면 인수 모드에서 구문 분석이 계속됩니다. 경로와 같은 공백이 포함된 인수가 있는 경우 해당 인수 값을 따옴표로 묶어야 합니다.

인수 모드는 셸 환경에서 명령에 대한 인수 및 매개 변수를 구문 분석하기 위해 설계되었습니다. 다음 구문 중 하나를 사용하지 않는 한 모든 입력은 확장 가능한 문자열로 처리됩니다.

  • 달러 기호()$ 다음에 변수 이름이 오면 변수 참조가 시작되고, 그렇지 않으면 확장 가능한 문자열의 일부로 해석됩니다. 변수 참조에는 멤버 액세스 또는 인덱싱이 포함될 수 있습니다.

    • $HOME같은 간단한 변수 참조를 따르는 추가 문자는 동일한 인수의 일부로 간주됩니다. 변수 이름을 중괄호({})로 묶어 후속 문자와 구분합니다. 예: ${HOME}.
    • 변수 참조에 멤버 액세스가 포함되면 추가 문자 중 첫 번째 문자가 새 인수의 시작으로 간주됩니다. 예를 들어 $HOME.Length-more는 두 개의 인수, 즉 $HOME.Length의 값과 문자열 리터럴 -more을 생성합니다.
  • 따옴표('")는 문자열을 시작합니다.

  • 중괄호({})는 새 스크립트 블록을 시작합니다.

  • 쉼표(,)는 호출할 명령이 기본 애플리케이션인 경우를 제외하고 배열로 전달된 목록을 도입하며, 이 경우 확장 가능한 문자열의 일부로 해석됩니다. 첫 번째 쉼표, 연속 쉼표 또는 후행 쉼표는 지원되지 않습니다.

  • 괄호 (())가 새 식을 시작합니다.

  • 하위 식 연산자($())가 포함된 식을 시작합니다.

  • initial at sign(@)은 스플래팅(@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 (문자열)

모든 토큰은 부울 또는 String같은 일종의 개체 형식으로 해석될 수 있습니다. PowerShell은 식에서 개체 형식을 확인하려고 시도합니다. 개체 형식은 명령이 예상하는 매개 변수의 형식과 PowerShell에서 인수를 올바른 형식으로 변환하는 방법을 알고 있는지에 따라 달라집니다. 다음 표에서는 식에서 반환된 값에 할당된 형식의 몇 가지 예를 보여 줍니다.

예시 모드 결과
Write-Output !1 논쟁 "!1"(문자열)
Write-Output (!1) 표현 거짓(논리형)
Write-Output (2) 표현 2(정수)
Set-Variable AB A,B 논쟁 'A', 'B' (배열)
CMD /CECHO A,B 논쟁 'A,B'(문자열)
CMD /CECHO $AB 표현 'A B'(배열)
CMD /CECHO :$AB 논쟁 ':A B'(문자열)

네이티브 명령에 인수 전달

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> 토큰은 as-is를 통해 전달됩니다.

스트림 리디렉션(예: >file.txt)은 대상 명령에 대한 인수로 그대로 전달되기 때문에 사용할 수 없습니다.

따옴표 문자가 포함된 인수 전달

일부 네이티브 명령에는 따옴표 문자가 포함된 인수가 사용됩니다. 일반적으로 PowerShell의 명령줄 구문 분석에서는 사용자가 제공한 따옴표 문자를 제거합니다. 구문 분석된 인수는 각 매개 변수를 공백으로 구분하여 단일 문자열로 조인합니다. 이 문자열은 개체의 Arguments 속성에 ProcessStartInfo 할당됩니다. 문자열 내의 따옴표는 추가 따옴표 또는 백슬래시(\) 문자를 사용하여 이스케이프해야 합니다.

비고

백슬래시(\) 문자는 PowerShell에서 이스케이프 문자로 인식되지 않습니다. 에 대한 ProcessStartInfo.Arguments기본 API에서 사용하는 이스케이프 문자입니다.

이스케이프 요구 사항에 대한 자세한 내용은 ProcessStartInfo.Arguments 설명서를 참조하세요.

도구를 사용하는 다음 예제입니다 TestExe.exe . 이 도구는 PowerShell 원본 리포지토리의 Pester 테스트에서 사용됩니다. 이러한 예제의 목표는 경로가 따옴표 붙은 문자열로 수신되도록 디렉터리 경로를 "C:\Program Files (x86)\Microsoft\" 네이티브 명령에 전달하는 것입니다.

echoargs실행 파일에 대한 인수로 수신된 값을 표시합니다. 이 도구를 사용하여 인수의 문자를 제대로 이스케이프했는지 확인할 수 있습니다.

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\\""

출력은 모든 예제에서 동일합니다.

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

소스 코드에서 TestExe 빌드할 수 있습니다. TestExe를 참조하세요.

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>

참고하십시오