about_Script_Internationalization
about_Script_Internationalization
여러 언어로 된 사용자에게 PowerShell 스크립트를 전달해야 할 때가 있어요. 메시지 하나를 만드는 데도 사용자가 쓰는 언어가 서로 달라서 곤란하죠. 이때 쓰는 기능이 바로 스크립트 국제화(script internationalization)예요. 한국어로는 대략 '스크립트 다국어 지원'이라고 부르면 돼요.
출처: about_Script_Internationalization - PowerShell | Microsoft Learn
본문
이 기능이 하는 일
PowerShell의 스크립트 국제화 기능을 쓰면 도움말과 사용자 메시지를 사용자의 언어로 보여줄 수 있어요. 운영체제의 UI 언어(UI culture)를 실행 시점에 확인해서, 해당 언어로 번역된 문자열을 불러와 화면에 표시하는 방식이에요.
이 과정을 돕는 핵심 요소가 몇 가지 있는데요. Data 섹션은 문자열을 코드와 분리해서 저장해요. 이렇게 분리해 두면 번역 대상 문자열을 쉽게 찾아낼 수 있죠. 그리고 ConvertFrom-StringData 라는 cmdlet이 문자열을 사전과 비슷한 해시 테이블로 바꿔줘서 번역을 훨씬 쉽게 만들어요.
국제화된 도움말을 지원하기 위해 PowerShell이 제공하는 기능은 이렇습니다.
- Data 섹션 — 문자열을 코드 명령과 분리해 저장해요. Data 섹션에 대한 자세한 내용은 about_Data_Sections를 참고하세요.
- 새 자동 변수 두 개 —
$PSCulture와$PSUICulture예요.$PSCulture는 시스템의 UI 언어 이름을 저장해요. 날짜, 시간, 통화 같은 요소에 쓰이는 언어죠.$PSUICulture는 메뉴나 문자열 같은 사용자 인터페이스 요소에 쓰이는 UI 언어 이름을 담아요. - cmdlet
ConvertFrom-StringData— 문자열을 사전과 비슷한 해시 테이블로 만들어 번역을 쉽게 해줘요. 자세한 내용은 ConvertFrom-StringData를 참고하세요. - 새 파일 형식
.psd1— 번역된 문자열을 저장해요. 이.psd1파일은 스크립트 디렉터리 아래의 언어별 하위 디렉터리에 저장됩니다. - cmdlet
Import-LocalizedData— 실행 시점에 지정된 언어의 번역 문자열을 스크립트로 가져와요. 이 cmdlet은 Windows에서 지원하는 모든 언어의 문자열을 인식하고 가져올 수 있어요. 자세한 내용은 Import-LocalizedData를 참고하세요.
Data 섹션: 기본 문자열 저장하기
기본 언어의 문자열을 저장할 때는 스크립트 안에 Data 섹션을 써요. 문자열을 here-string 안에 키/값 쌍으로 정리해서 넣으면 되고, 각 키/값 쌍은 반드시 한 줄씩 따로 둬야 해요. 주석을 포함한다면 주석도 각각 별도의 줄에 있어야 합니다.
ConvertFrom-StringData cmdlet은 here-string 안의 키/값 쌍을 사전과 비슷한 해시 테이블로 바꾸고, 그 결과를 Data 섹션 변수의 값으로 저장해요.
아래 예시에서 World.ps1 스크립트의 Data 섹션은 영어-미국(en-US) 버전의 프롬프트 메시지 모음을 담고 있어요. ConvertFrom-StringData cmdlet이 문자열을 해시 테이블로 바꿔 $msgtable 변수에 저장합니다.
$msgTable = data {
#culture="en-US"
ConvertFrom-StringData @'
helloWorld = Hello, World.
errorMsg1 = You cannot leave the user name field blank.
promptMsg = Please enter your user name.
'@
}
here-string에 대한 자세한 내용은 about_Quoting_Rules를 참고하세요.
PSD1 파일: 번역된 문자열 저장하기
각 UI 언어의 스크립트 메시지는 스크립트와 같은 이름에 .psd1 확장자를 붙인 별도의 텍스트 파일로 저장해요. 이 파일들은 스크립트 디렉터리 아래에 아래 형식의 문화 이름을 딴 하위 디렉터리에 둡니다.
<language>-<region>
몇 가지 예를 들면 de-DE, ar-SA, zh-Hans 같은 형식이에요.
예를 들어 World.ps1 스크립트가 C:\Scripts 디렉터리에 있다고 해볼게요. 그럼 다음과 같은 디렉터리 구조가 만들어집니다.
C:\Scripts
C:\Scripts\World.ps1
C:\Scripts\de-DE\World.psd1
C:\Scripts\ar-SA\World.psd1
C:\Scripts\zh-CN\World.psd1
...
스크립트 디렉터리 아래 de-DE 하위 디렉터리의 World.psd1 파일은 아마 이런 내용을 담고 있을 거예요.
ConvertFrom-StringData -StringData @'
helloWorld = Hallo, Welt.
errorMsg1 = Das Feld Benutzername darf nicht leer sein.
promptMsg = Geben Sie Ihren Benutzernamen ein.
'@
비슷하게 ar-SA 하위 디렉터리의 World.psd1 파일은 이런 문장을 담을 수 있어요.
ConvertFrom-StringData -StringData @'
helloWorld = مرحبًا أيها العالَم
errorMsg1 = لا يمكنك ترك حقل اسم المستخدم فارغًا
promptMsg = يرجى إدخال اسم المستخدم الخاص بك
'@
Import-LocalizedData: 번역 문자열 동적 가져오기
현재 사용자의 UI 언어로 된 문자열을 가져올 때는 Import-LocalizedData cmdlet을 사용해요.
이 cmdlet은 $PSUICulture 자동 변수의 값을 찾아서, 그 값과 일치하는 하위 디렉터리에 있는 <script-name>.psd1 파일의 내용을 가져와요. 그리고 가져온 내용을 BindingVariable 매개 변수 값으로 지정한 변수에 저장합니다.
Import-LocalizedData -BindingVariable msgTable
예를 들어 C:\Scripts\World.ps1 스크립트에 Import-LocalizedData 명령이 있고, $PSUICulture 값이 "ar-SA"라면, 이 cmdlet은 다음 파일을 찾아요.
C:\Scripts\ar-SA\World.psd1
그리고 그 파일에서 아랍어 문자열을 가져와 $msgTable 변수에 저장해요. 이때 World.ps1 스크립트의 Data 섹션에 정의된 기본 문자열은 그대로 두고, 가져온 값으로 대체됩니다.
그 결과, 스크립트가 $msgTable 변수로 사용자 메시지를 보여줄 때 메시지가 아랍어로 표시돼요.
예를 들어 아래 스크립트는 "Please enter your user name" 메시지를 아랍어로 보여줍니다.
if (!($username)) { $msgTable.promptMsg }
만약 Import-LocalizedData가 $PSUICulture 값과 일치하는 .psd1 파일을 찾지 못하면, $msgTable 값은 바뀌지 않아요. 그래서 $msgTable.promptMsg 호출은 기본값인 en-US 문자열을 그대로 보여줍니다.
예제
이 예제는 스크립트 국제화 기능을 실제 스크립트에서 어떻게 쓰는지 보여줘요. 컴퓨터에 설정된 언어로 요일 이름을 사용자에게 보여주는 스크립트예요.
다음은 Sample1.ps1 스크립트 파일의 전체 모습입니다.
스크립트는 이름이 Day($Day)인 Data 섹션으로 시작해요. 이 섹션에는 ConvertFrom-StringData 명령이 들어 있고, 여기에 전달하는 표현식은 기본 UI 문화인 en-US의 요일 이름을 키/값 쌍으로 담은 here-string이에요. ConvertFrom-StringData cmdlet은 here-string의 키/값 쌍을 해시 테이블로 바꾸어 $Day 변수의 값으로 저장합니다.
Import-LocalizedData 명령은 $PSUICulture 자동 변수의 값과 일치하는 디렉터리에 있는 .psd1 파일의 내용을 가져와 $Day 변수에 저장해요. 이때 Data 섹션에 정의된 $Day 값들은 가져온 값으로 대체됩니다.
나머지 명령은 문자열을 배열로 불러와 화면에 표시합니다.
$Day = data {
#culture="en-US"
ConvertFrom-StringData -StringData @'
messageDate = Today is
d0 = Sunday
d1 = Monday
d2 = Tuesday
d3 = Wednesday
d4 = Thursday
d5 = Friday
d6 = Saturday
'@
}
Import-LocalizedData -BindingVariable Day
#Build an array of weekdays.
$a = $Day.d0, $Day.d1, $Day.d2, $Day.d3, $Day.d4, $Day.d5, $Day.d6
# Get the day of the week as a number (Monday = 1).
# Index into $a to get the name of the day.
# Use string formatting to build a sentence.
"{0} {1}" -f $Day.messageDate, $a[(Get-Date -UFormat %u)] | Out-Host
스크립트를 뒷받침하는 .psd1 파일들은 스크립트 디렉터리의 하위 디렉터리에 저장되는데, 그 이름이 $PSUICulture 값과 일치합니다.
다음은 .\de-DE\sample1.psd1의 전체 모습입니다.
# culture="de-DE"
ConvertFrom-StringData @'
messageDate = Heute ist
d0 = Sonntag
d1 = Montag
d2 = Dienstag
d3 = Mittwoch
d4 = Donnerstag
d5 = Freitag
d6 = Samstag
'@
그 결과, $PSUICulture 값이 de-DE인 시스템에서 Sample.ps1을 실행하면 스크립트의 출력은 이렇게 나옵니다.
Heute ist Freitag