Power Shell2009. 12. 15. 21:41

유닉스의 전통적인 장점은 내장 스크립트를 지원하는 셸과 스크립트 작성에 요긴한 명령행 유틸리티를 풍부하게 보유하고 있다는 점입니다. 반면 윈도는 스크립트라고는 도스 시절부터 그대로 내려온 배치 파일이 고작인데, 문법과 기능이 너무 조악한 관계로 요즘 사용자들의 눈높이로는 스크립트라고 부르기도 민망한 수준입니다. 

많은 용도가 있지만 스크립트가 유용하게 쓰이는 분야는 특히 서버 운영의 자동화입니다. 유닉스가 그 동안 윈도에 완전히 압도 당하지 않고 시장에서 꾸준히 생존해 온 이유 중 하나가 스크립트를 잘 지원한 덕분이기도 했습니다. 하지만 이 우위는 작년에 마이크로소프트가 야심적으로 발표한 PowerShell이란 새로운 셸에 의해 도전을 받게 된 듯 합니다.

버전 1.0이란 태그를 달고 첫선을 보인 PowerShell(이하 PS)은 특이하게도 네이티브 Win32가 아닌 닷넷 프레임워크 2.0 기반의 애플리케이션입니다. 윈도 XP에서는 운영 체제의 일부로 %SystemRoot%\System32 디렉토리 밑에 설치됩니다. 지난 며칠 동안 살펴 본 PS는 일단 스크립트 언어의 문법이 펄과 아주 유사하게 생겼지만 완전히 같지는 않고, 파이썬과 비슷하게 대화형 모드를 기본 지원하며, 유닉스처럼 파이프의 사용에 크게 의존하고, 전체적인 명령과 문법이 상당히 일관적이고, 닷넷 런타임과 쉽게 연동 가능하며, 최신 기술 답게 유니코드 인코딩과 문자셋간 변환 등을 잘 지원합니다. 펄과도 비슷하고, 파이썬과도 비슷하고, 유닉스와도 비슷하면서 닷넷과 연동된다니, 일단 뭔가 거대한 것이 있을 듯한 느낌이 들었습니다만... :-) 학습 난이도는 유닉스 셸 프로그래밍 경험이 있는 사용자라면 누구나 어렵지 않게 배울 수 있을 것 같고, 특히 펄 사용자라면 아주 빨리 적응할 것 같습니다.

저도 아직 맛보기만 몇 가지 해본 정도라서 고급 내용을 소개하기는 어렵고, 오늘은 간단한 실행법만 소개하도록 하겠습니다.

PS를 실행하면 cmd.exe를 실행한 것과 비슷한 화면이 뜹니다.
Windows PowerShell
Copyright (C) 2006 Microsoft Corporation. All rights reserved.

PS C:\Documents and Settings\Hwychol.AHN>

이 상태에서 파이썬처럼 간이 계산기로 사용이 가능합니다:
PS C:\Documents and Settings\Hwychol.AHN> 100/13
7.69230769230769

역시 파이썬과 마찬가지로 명령행에서 바로 변수를 사용할 수도 있는데, 변수는 이름 앞에 $를 붙입니다(어디서 많이 보던 방식이지요? :-) 변수는 사용하기 전 정의하거나 타입을 지정할 필요가 없어서 아래처럼 바로 사용이 가능합니다:
PS C:\Documents and Settings\Hwychol.AHN> $a = 1
PS C:\Documents and Settings\Hwychol.AHN> $a
1
PS C:\Documents and Settings\Hwychol.AHN> $a+1
2

명령행에서 바로 치는 것 말고 스크립트 파일로 저장해서 실행할 때는 확장자로 .ps1을 붙입니다. 나중에 버전 2, 3, ...이 나왔을 때 끝의 숫자로 구분하기 위한 모양입니다. 아무 에디터로 다음 내용을 입력한 다음 test.ps1라고 저장해 봅시다:

$a = 1
$a


이렇게 한 다음 명령행에선

PS C:\Documents and Settings\Hwychol.AHN> .\test.ps1


이라고 쳐서 실행합니다. 현재 디렉토리에 있는 스크립트를 실행할 때 .\를 앞에 꼭 붙여야 한다는 점을 유의해야겠습니다(이 점도 유닉스의 영향을 받은 부분이군요).

그런데 실제로 위의 명령을 실행하려고 하면

PS C:\Documents and Settings\Hwychol.AHN> .\test.ps1
File C:\Documents and Settings\Hwychol.AHN\test.ps1 cannot be loaded because the execution of scripts is disabled on this
system. Please see "get-help about_signing" for more details.
At line:1 char:10
+ .\test.ps1 <<<<


라고 무시무시한 에러가 나 버립니다. 이런 황당함이란...ㅡ.ㅡ 사실 이 에러는 보안상 의도된 것으로, 실행 정책을 변경해 주어야 스크립트 실행이 가능해집니다. 실행 정책의 변경은 아래 명령으로 합니다:

PS C:\Documents and Settings\Hwychol.AHN> Set-ExecutionPolicy RemoteSigned


제대로 바뀌었는지 Get-ExecutionPolicy로 확인할 수 있습니다:

PS C:\Documents and Settings\Hwychol.AHN> Get-ExecutionPolicy
RemoteSigned


참고로 PS는 대소문자 구별에 관대하기 때문에 set-executionpolicy, get-executionpolicy, remotesigned라고 쳐도 됩니다.

이제 다시 test.ps1을 실행해 보면 결과가 정상적으로 출력되는 것을 볼 수 있습니다:

PS C:\Documents and Settings\Hwychol.AHN> .\test.ps1
1

PS 스크립트는 C나 펄 계열처럼 들여쓰기를 자유롭게 할 수 있습니다. 아래 예에서는 보기 좋게 하려고 일부러 줄을 많이 바꿨지만 전체 문장을 한 줄로 써도 됩니다.

코멘트

셸 스크립트라 그런지 코멘트는 싱글 라인 코멘트 #만 쓸 수 있습니다.

크기 비교 연산자

C에 대응하는 PS의 크기 비교 연산자는 다음과 같습니다.



-gt, -lt 같은 이해하기 힘든 기호를 쓰는 이유는 >, < 기호를 리디렉션 용도로 쓰기 때문입니다. 그렇지만 일단 익히고 나면 유닉스 셸이나 펄을 배울 때 연산자를 다시 익힐 필요가 없는 장점이 보너스로 생깁니다.

연산자는 결과로 참 아니면 거짓을 리턴합니다. 즉,

PS> 7 -eq 5
True


이 되겠습니다.

이들 크기 비교 연산자를 -and, -or 등의 논리 연산자와 섞어 쓰면 훌륭한 식이 됩니다. 예를 들어

PS> (7 -lt 10) -and (5 -gt 3)
True


기본 문법(?)을 익혔으니 이제는 제어 구문을 하나씩 들여다 보기로 하겠습니다.

if 문

if ($count -lt 5) # $count가 5보다 작으면
{
"foo!"
}
elseif ($number -gt 1000) # 그렇지 않고 $number가 1000보다 크면
{
"bar!"
}
else # 이것도 저것도 아니면
{
"duh!"
}


elsif 대신 elseif라는 점을 제외하고는 펄과 거의 같습니다. {, } 기호는 필수라서 블럭 안에 문장이 하나만 있어도 생략하면 안됩니다.

switch 문

switch ($count)
{
{$_ -lt 5} # $_가 5보다 작으면 다음 블럭을 실행
{ "foo!" }

10 # { $_ -eq 10 }의 축약형. "case 10:"이라고 읽으면 됩니다.
{ "bar!" }

default # C의 default: 와 같음
{ "duh!" }
}


switch 문내에서 쓰이는 $_ 변수는 switch 괄호안의 결과값을 뜻합니다. 여기서는 $count의 값이 되겠습니다.

for 문

for ($i = 0; $i -lt 10; $i++)
{
"foo!"
}


for문은 그다지 특별한 점이 없는 것 같군요.

while 문

while ($i -le 10)
{
"foo!"
}


while도 마찬가지.

foreach 문

foreach ($i in 1..5)
{
$i
}


요즘 유행하는(?) foreach가 PS에도 있습니다. 위에서는 1부터 5까지로 이루어진 배열(1..5)로부터 하나씩 값을 받아 화면에 찍습니다. 이 foreach는 상당히 재미있는 형태로 응용할 수 있는데, 예를 들어 위의 문장을 파이프를 쓰는 형태로

1..5 | foreach { $_ }


라고 써도 같은 결과가 나옵니다. foreach의 오묘한 세계는 따로 뽑아 단독 특집을 꾸며도 재미있을 듯...

do...while 문

$i = 1;
do
{
$i ; $i++ # 한 줄에 명령을 여러 개 쓸 때에는 ;로 구분합니다
}
while ($i -lt 10)


do...while문은 별로 안쓰는 루프지만 PS에도 있군요. 뜻은 다른 언어에서와 마찬가지로 '~할 동안 실행하라'가 되겠습니다. $i가 10보다 작을 동안 루프를 계속 돕니다.

do...until 문

$i = 1;
do
{
$i ; $i++
}
until ($i -gt 10)


do...until 문은 do...while 문과 반대로 '~할 때까지 실행하라'는 뜻입니다(파스칼의 repeat...until과 같은 용법?). 위 예에서는 $i가 10보다 커질 때까지 루프를 계속 돕니다.
목록


http://cafe.naver.com/ArticleRead.nhn?clubid=12200394&page=1&menuid=50&boardtype=&articleid=4145

Posted by 동동(이재동)