빌드노트
PowerShell이 [draft].txt 대신 d.txt를 찾는 이유
PowerShell의 Path는 따옴표로 감싼 [draft].txt도 패턴으로 읽는다. PowerShell 7.6.6에서 대괄호 파일과 d.txt의 조회·존재 검사를 비교하고, 실제 이름을 지정할 때 LiteralPath를 선택하는 방법을 설명한다.
탐색기에 보이는 [draft].txt를 PowerShell의 Get-Item으로 조회했는데 아무것도 나오지 않거나 d.txt가 나온다면, Path가 파일 이름을 패턴으로 읽고 있는지 확인한다. 이름 그대로 한 파일을 지정하려면 `LiteralPath`를 사용한다. 작은따옴표로 감싸는 것만으로는 Path의 와일드카드 해석이 꺼지지 않는다.
먼저 자신의 파일에 적용할 조회다. PowerShell에서 $file을 실제 파일의 전체 경로로 바꿔 실행하면, 그 이름의 항목과 파일 여부를 확인할 수 있다.
$file = 'C:\work\[draft].txt'
Get-Item -LiteralPath $file | Select-Object -ExpandProperty Name
Test-Path -LiteralPath $file -PathType Leaf
그 경로에 일반 파일이 있으면 이름은 [draft].txt, 검사 결과는 True다. 여전히 실패하면 Get-Item의 오류 메시지와 경로를 확인한다. LiteralPath는 잘못된 폴더나 파일 이름을 고쳐 주지 않으며, Leaf 검사는 같은 이름의 디렉터리가 있어도 False를 반환한다. Test-Path의 LiteralPath와 PathType 설명 (새 탭에서 열림)
[draft]는 draft라는 단어를 뜻하지 않는다
PowerShell의 와일드카드에서 대괄호는 그 안에 나열한 문자 중 한 글자를 고르는 패턴이다. [draft].txt는 d.txt, r.txt 같은 이름에 맞는다. 대괄호를 포함한 [draft].txt라는 이름이나 다섯 글자가 이어지는 draft.txt를 뜻하지 않는다. about_Wildcards의 대괄호 규칙 (새 탭에서 열림)
Get-Item의 Path는 이런 패턴을 허용한다. 매개변수 이름을 생략한 Get-Item '.\[draft].txt'도 Path로 전달된다. 반면 LiteralPath는 전달받은 경로의 문자를 와일드카드로 해석하지 않는다. 이 파일을 조회할 때는 대괄호 앞에 백틱을 덧붙이지 않고 원래 경로를 넣는다. Get-Item의 Path와 LiteralPath 설명 (새 탭에서 열림)
True가 나와도 어느 파일을 찾았는지 봐야 한다
새 실험 폴더에서 두 파일을 만들고 같은 문자열로 조회를 비교했다. 직접 따라 하려면 PowerShell에서 새로 만든 빈 폴더를 현재 위치로 열고 아래를 실행한다. 앞의 두 줄은 비교용 파일을 만들므로 기존 파일이 있는 폴더에서는 실행하지 않는다.
Set-Content -LiteralPath '.\[draft].txt' -Value 'literal'
Set-Content -LiteralPath '.\d.txt' -Value 'pattern'
Get-Item -Path '.\[draft].txt' | Select-Object -ExpandProperty Name
Get-Item -LiteralPath '.\[draft].txt' | Select-Object -ExpandProperty Name
Test-Path -Path '.\[draft].txt'
Test-Path -LiteralPath '.\[draft].txt'
Windows의 PowerShell 7.6.6, FileSystem 공급자에서 조회 네 줄은 차례로 d.txt, [draft].txt, True, True를 출력했다. 두 검사가 모두 참이지만 같은 파일을 확인한 것이 아니다. 첫 번째 True는 d.txt가 패턴에 맞아서 나온 결과다. 이 비교에서 Path의 작은따옴표를 큰따옴표로 바꾸거나 경로를 변수에 넣어도 Get-Item은 d.txt를 반환했다.
파일 구성만 달리한 별도 새 폴더에서는 다음 차이도 관찰했다. 기존 파일을 지우거나 옮겨 만든 조건은 아니다.
[draft].txt만 있으면Get-Item -Path는 출력이 없었고Test-Path -Path는False였다.LiteralPath조회는[draft].txt, 검사는True였다.d.txt만 있으면Path조회는d.txt, 검사는True였다.LiteralPath조회는 경로를 찾지 못했다는 오류, 검사는False였다.
따라서 Test-Path -Path의 결과만으로 대괄호를 포함한 파일의 존재를 판단하면 양쪽으로 틀릴 수 있다. 파일 하나의 존재를 검사하는 코드라면 조회뿐 아니라 검사에도 LiteralPath를 사용한다.
쓰려는 명령에 LiteralPath가 있는지 확인한다
경로를 받는 모든 명령이 LiteralPath를 제공하는 것은 아니다. 아래처럼 현재 명령의 매개변수를 조회해 지원 여부를 확인할 수 있다. 두 명령은 실험 환경에서 모두 True였다. Get-Command 설명 (새 탭에서 열림)
(Get-Command -Name Get-Item).Parameters.ContainsKey('LiteralPath')
(Get-Command -Name Test-Path).Parameters.ContainsKey('LiteralPath')
없는 명령에는 같은 옵션을 붙이지 말고 해당 명령의 경로 처리와 이스케이프 규칙을 확인한다. 여러 파일을 패턴으로 찾으려는 목적이면 Path를 유지하고, 이미 알고 있는 실제 이름을 전달하려는 목적이면 지원되는 LiteralPath를 선택한다.
여기서 직접 확인한 범위는 Windows의 PowerShell 7.6.6에서 일반 파일을 조회하는 동작이다. 추가로 시도한 기본 Windows PowerShell 비교는 완료하지 못했으므로 그 결과를 검증 근거로 삼지 않았다. 다른 운영체제·공급자와 삭제·이동 명령의 동작은 실행하지 않았다.