VS Code 및 PowerShell의 파일 인코딩 이해
VS Code를 사용하여 PowerShell 스크립트를 만들고 편집하는 경우 올바른 문자 인코딩 형식을 사용하여 파일을 저장하는 것이 중요합니다.
파일 인코딩이란 무엇이며 왜 중요한가요?
VS Code는 사용자가 버퍼에 문자 문자열을 입력하고 파일 시스템에 바이트 블록을 읽거나 쓰는 인터페이스를 관리합니다. VS Code는 파일을 저장할 때 텍스트 인코딩을 사용하여 각 문자가 되는 바이트를 결정합니다. 자세한 내용은 about_Character_Encoding참조하세요.
마찬가지로 PowerShell에서 스크립트를 실행할 때 파일을 PowerShell 프로그램으로 다시 구성하려면 파일의 바이트를 문자로 변환해야 합니다. VS Code는 파일을 작성하고 PowerShell은 파일을 읽기 때문에 동일한 인코딩 시스템을 사용해야 합니다. PowerShell 스크립트를 구문 분석하는 이 프로세스는
VS Code와 PowerShell은 모두 합리적인 기본 인코딩 구성으로 설치됩니다. 그러나 PowerShell에서 사용하는 기본 인코딩은 PowerShell 6 릴리스와 함께 변경되었습니다. VS Code에서 PowerShell 또는 PowerShell 확장을 사용하는 데 문제가 없도록 하려면 VS Code 및 PowerShell 설정을 올바르게 구성해야 합니다.
인코딩 문제의 일반적인 원인
VS Code 또는 스크립트 파일의 인코딩이 PowerShell의 예상 인코딩과 일치하지 않는 경우 인코딩 문제가 발생합니다. PowerShell에서 파일 인코딩을 자동으로 확인할 수 있는 방법은 없습니다.
7비트 ASCII 문자 집합없는 문자를 사용하는 경우 인코딩 문제가 발생할 가능성이 높습니다. 예를 들어:
- em-dash(
—
), 나누지 않는 공백("
)와 같은 문자가 아닌 확장 문자 - 강조된 라틴 문자(
É
,ü
) - 키릴 자모(
Д
,Ц
)와 같은 라틴 문자가 아닌 문자 - CJK 문자(
本
,화
,が
)
인코딩 문제의 일반적인 이유는 다음과 같습니다.
- VS Code 및 PowerShell의 인코딩은 기본값에서 변경되지 않았습니다. PowerShell 5.1 이하의 경우 기본 인코딩은 VS Code와 다릅니다.
- 다른 편집기가 새 인코딩에서 파일을 열고 덮어씁니다. 이는 종종 ISE에서 발생합니다.
- 파일이 VS Code 또는 PowerShell에서 예상하는 것과 다른 인코딩에서 소스 제어로 체크 인됩니다. 공동 작업자가 다른 인코딩 구성이 있는 편집기를 사용할 때 이 문제가 발생할 수 있습니다.
인코딩 문제가 있는 경우를 알려주는 방법
종종 인코딩 오류는 스크립트에서 구문 분석 오류로 나타납니다. 스크립트에서 이상한 문자 시퀀스를 발견하면 문제가 될 수 있습니다. 아래 예제에서는 문자 –
en-dash(â€"
)가 나타납니다.
Send-MailMessage : A positional parameter cannot be found that accepts argument 'Testing FuseMail SMTP...'.
At C:\Users\<User>\<OneDrive>\Development\PowerShell\Scripts\Send-EmailUsingSmtpRelay.ps1:6 char:1
+ Send-MailMessage â€"From $from â€"To $recipient1 â€"Subject $subject ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Send-MailMessage], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SendMailMessage
VS Code는 UTF-8의 문자 –
바이트 0xE2 0x80 0x93
인코딩하기 때문에 이 문제가 발생합니다. 이러한 바이트가 Windows-1252로 디코딩되면 â€"
문자로 해석됩니다.
표시될 수 있는 몇 가지 이상한 문자 시퀀스는 다음과 같습니다.
-
â€"
대신–
(en-dash) -
â€"
대신—
(em 대시) -
Ä2
대신Ä
-
Â
대신 -
é
대신é
이 편리한 참조 UTF-8/Windows-1252 인코딩 문제를 나타내는 일반적인 패턴을 나열합니다.
VS Code의 PowerShell 확장이 인코딩과 상호 작용하는 방법
PowerShell 확장은 다음과 같은 다양한 방법으로 스크립트와 상호 작용합니다.
- VS Code에서 스크립트를 편집하면 VS Code에서 확장에 콘텐츠를 보냅니다. 언어 서버 프로토콜 이 콘텐츠가 UTF-8로 전송되도록 규정하고 있습니다. 따라서 확장에서 잘못된 인코딩을 가져올 수 없습니다.
- 통합 콘솔에서 직접 스크립트를 실행하면 PowerShell에서 직접 파일에서 읽습니다. PowerShell의 인코딩이 VS Code의 인코딩과 다른 경우 여기에서 문제가 발생할 수 있습니다.
- VS Code에서 열려 있는 스크립트가 VS Code에서 열려 있지 않은 다른 스크립트를 참조하는 경우 확장은 파일 시스템에서 해당 스크립트의 콘텐츠를 로드하는 것으로 돌아갑니다. PowerShell 확장은 기본적으로 UTF-8 인코딩으로 설정되지만 바이트 순서 표시또는 BOM 검색을 사용하여 올바른 인코딩을 선택합니다.
BOM이 없는 형식(예: BOM이 없는
올바른 인코딩 선택
시스템 및 애플리케이션이 서로 다른 인코딩을 사용할 수 있습니다.
- .NET Standard, 웹 및 Linux 세계에서 UTF-8은 이제 주요 인코딩입니다.
- 많은 .NET Framework 애플리케이션은 UTF-16
사용합니다. 역사적 이유로 이 용어는 UTF-8 및 UTF-16을 모두 포함하는 광범위한 표준 참조하는 용어인 "유니코드"라고도 합니다. - Windows에서는 유니코드 이전의 많은 네이티브 애플리케이션에서 기본적으로 Windows-1252를 계속 사용합니다.
유니코드 인코딩에는 BOM(바이트 순서 표시) 개념도 있습니다. BOM은 텍스트의 시작 부분에서 발생하여 텍스트가 사용 중인 인코딩을 디코더에 알립니다. 다중 바이트 인코딩의 경우 BOM은 인코딩의 엔디언성 나타냅니다. BOM은 유니코드가 아닌 텍스트에서 거의 발생하지 않는 바이트로 설계되어 BOM이 있을 때 텍스트가 유니코드라고 합리적으로 추측할 수 있습니다.
BOM은 선택 사항이며, UTF-8의 신뢰할 수 있는 규칙이 모든 곳에서 사용되기 때문에 LINux 환경에서는 채택이 인기가 없습니다. 대부분의 Linux 애플리케이션은 텍스트 입력이 UTF-8로 인코딩된 것으로 가정합니다. 많은 Linux 애플리케이션이 BOM을 인식하고 올바르게 처리하지만 숫자는 인식되지 않으므로 해당 애플리케이션으로 조작된 텍스트의 아티팩트가 표시됩니다.
따라서 다음을.
- Windows 애플리케이션 및 Windows PowerShell을 주로 사용하는 경우 BOM 또는 UTF-16을 사용하는 UTF-8과 같은 인코딩을 선호해야 합니다.
- 여러 플랫폼에서 작업하는 경우 BOM을 사용하는 UTF-8을 선호해야 합니다.
- Linux 관련 컨텍스트에서 주로 작업하는 경우 BOM 없이 UTF-8을 선호해야 합니다.
- Windows-1252 및 latin-1은 기본적으로 가능한 경우 피해야 하는 레거시 인코딩입니다. 그러나 일부 이전 Windows 애플리케이션은 이에 따라 달라질 수 있습니다.
- 또한 스크립트 서명이 인코딩 종속
주목할 필요가 있습니다. 즉, 서명된 스크립트에서 인코딩을 변경하려면 사임이 필요합니다.
VS Code 구성
VS Code의 기본 인코딩은 BOM이 없는 UTF-8입니다.
VS Code의 인코딩
"files.encoding": "utf8bom"
가능한 값은 다음과 같습니다.
-
utf8
: BOM이 없는 [UTF-8] -
utf8bom
: BOM을 사용하는 [UTF-8] -
utf16le
: Little endian [UTF-16] -
utf16be
: 빅 엔디안 [UTF-16] -
windows1252
: [Windows-1252]
GUI 보기에서 이에 대한 드롭다운을 얻거나 JSON 보기에서 완료해야 합니다.
가능한 경우 인코딩을 자동으로 검색하기 위해 다음을 추가할 수도 있습니다.
"files.autoGuessEncoding": true
이러한 설정이 모든 파일 형식에 영향을 주지 않도록 하려면 VS Code에서 언어별 구성도 허용합니다.
[<language-name>]
필드에 설정을 배치하여 언어별 설정을 만듭니다. 예를 들어:
"[powershell]": {
"files.encoding": "utf8bom",
"files.autoGuessEncoding": true
}
Visual Studio Code용 Gremlins 추적기 설치하는 것도 고려할 수 있습니다. 이 확장은 보이지 않거나 다른 일반 문자처럼 보이기 때문에 쉽게 손상된 특정 유니코드 문자를 표시합니다.
PowerShell 구성
PowerShell의 기본 인코딩은 버전에 따라 다릅니다.
- PowerShell 6 이상에서 기본 인코딩은 모든 플랫폼에서 BOM이 없는 UTF-8입니다.
- Windows PowerShell에서 기본 인코딩은 일반적으로 Windows-1252이며, 이는 latin-1(ISO 8859-1이라고도 함)의 확장입니다.
PowerShell 5 이상에서는 다음을 사용하여 기본 인코딩을 찾을 수 있습니다.
[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
ForEach-Object {
$_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
}
다음 스크립트 사용하여 BOM 없이 스크립트에 대해 PowerShell 세션이 유추하는 인코딩을 결정할 수 있습니다.
$badBytes = [byte[]]@(0xC3, 0x80)
$utf8Str = [System.Text.Encoding]::UTF8.GetString($badBytes)
$bytes = [System.Text.Encoding]::ASCII.GetBytes('Write-Output "') + [byte[]]@(0xC3, 0x80) + [byte[]]@(0x22)
$path = Join-Path ([System.IO.Path]::GetTempPath()) 'encodingtest.ps1'
try
{
[System.IO.File]::WriteAllBytes($path, $bytes)
switch (& $path)
{
$utf8Str
{
return 'UTF-8'
break
}
default
{
return 'Windows-1252'
break
}
}
}
finally
{
Remove-Item $path
}
프로필 설정을 사용하여 지정된 인코딩을 더 일반적으로 사용하도록 PowerShell을 구성할 수 있습니다. 다음 문서를 참조하세요.
- 스택 오버플로PowerShell 인코딩에 대한
답변입니다. - PowerShellBOM이 없는 UTF-8 입력을 처리하는 방법에 대한
블로그 게시물입니다.
PowerShell에서 특정 입력 인코딩을 사용하도록 강제할 수 없습니다. 로캘이 en-US설정된 Windows에서 실행되는 PowerShell 5.1 이하에서는 BOM이 없는 경우 기본적으로 Windows-1252 인코딩으로 설정됩니다. 다른 로캘 설정은 다른 인코딩을 사용할 수 있습니다. 상호 운용성을 보장하기 위해 BOM을 사용하여 유니코드 형식으로 스크립트를 저장하는 것이 가장 좋습니다.
중요하다
PowerShell 스크립트를 터치하는 다른 도구는 인코딩 선택 항목의 영향을 받거나 스크립트를 다른 인코딩으로 다시 인코딩할 수 있습니다.
기존 스크립트
파일 시스템에 이미 있는 스크립트는 선택한 새 인코딩으로 다시 인코딩해야 할 수 있습니다. VS Code의 아래쪽 막대에 UTF-8 레이블이 표시됩니다. 작업 모음을 열고 인코딩
여러 파일을 다시 인코딩해야 하는 경우 다음 스크립트를 사용할 수 있습니다.
Get-ChildItem *.ps1 -Recurse | ForEach-Object {
$content = Get-Content -Path $_
Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}
PowerShell ISE(통합 스크립팅 환경)
PowerShell ISE를 사용하여 스크립트를 편집하는 경우 인코딩 설정을 동기화해야 합니다.
ISE는 BOM을 적용해야 하지만 리플렉션을 사용하여 인코딩
소스 제어 소프트웨어
git와 같은 일부 소스 제어 도구는 인코딩을 무시합니다. git은 바이트를 추적합니다. Azure DevOps 또는 Mercurial과 같은 다른 사용자는 그렇지 않을 수 있습니다. 일부 git 기반 도구도 텍스트 디코딩을 사용합니다.
이 경우 다음을 확인합니다.
- VS Code 구성과 일치하도록 소스 제어에서 텍스트 인코딩을 구성합니다.
- 모든 파일이 관련 인코딩의 소스 제어에 체크 인되었는지 확인합니다.
- 소스 제어를 통해 받은 인코딩에 대한 변경 내용을 주의해야 합니다. 이 것의 주요 징후는 변경 내용을 나타내는 차이이지만 아무 것도 변경되지 않은 것처럼 보입니다(바이트는 있지만 문자는 변경되지 않았기 때문).
협력자의 환경
소스 제어를 구성하는 것에서 공유하는 모든 파일의 협력자가 PowerShell 파일을 다시 인코딩하여 인코딩을 재정의하는 설정이 없는지 확인합니다.
기타 프로그램
PowerShell 스크립트를 읽거나 쓰는 다른 프로그램은 다시 인코딩할 수 있습니다.
몇 가지 예는 다음과 같습니다.
- 클립보드를 사용하여 스크립트를 복사하여 붙여넣습니다. 이는 다음과 같은 시나리오에서 일반적입니다.
- VM에 스크립트 복사
- 전자 메일 또는 웹 페이지에서 스크립트 복사
- Microsoft Word 또는 PowerPoint 문서로 또는 외부로 스크립트 복사
- 기타 텍스트 편집기( 예:
- 메모장
- vim
- 다른 PowerShell 스크립트 편집기
- 다음과 같은 텍스트 편집 유틸리티:
Get-Content
/Set-Content
/Out-File
-
>
및>>
같은 PowerShell 리디렉션 연산자 sed
/awk
- 다음과 같은 파일 전송 프로그램:
- 스크립트를 다운로드할 때 웹 브라우저
- 파일 공유
이러한 도구 중 일부는 텍스트가 아닌 바이트를 처리하지만 다른 도구는 인코딩 구성을 제공합니다. 인코딩을 구성해야 하는 경우 문제를 방지하기 위해 편집기 인코딩과 동일하게 만들어야 합니다.
PowerShell의 인코딩에 대한 기타 리소스
PowerShell에서 인코딩 및 구성에 대한 몇 가지 다른 유용한 게시물은 읽을 만한 가치가 있습니다.
PowerShell