Tcl의 문법

admin의 아바타

Tcl의 문법은 상당히 단순하고, 커맨드의 인자를 스페이스(공백)로 단락을 짓고 나열하는 정도입니다.

command arg1 arg2 arg3 ...

한행에 여러개의 커맨드를 나열할때는, 세미콜론( ; )으로 구분을 짓습니다.

command arg1 arg2 arg3 ... ; command arg1 arg2 arg3 ...

한행이 길어질때는, 행 끝에 백슬래쉬(\)를 두는 것으로 계속 이어쓸수 있습니다.

command arg1 \
    arg2 arg3 ...

다음의 간단한 예제를 보겠습니다.

Hello World

Hello World를 표시하는 스크립트입니다. puts 커맨드는 문자를 표시하는 커맨드입니다. 두개의 예제는 같은 결과를 나타냅니다.

puts stdout {Hello World}
=>Hello World
puts stderr {Hello World}
=>Hello World
puts {Hello World}
=>Hello World
puts stdout "Hello World"
=>Hello World
puts stderr "Hello World"
=>Hello World
puts "Hello World"
=>Hello World

변수

Tcl의 변수에는 타입이 없습니다. 타입을 의식하지 않고 문자열이나 정수를 변수에 대입할수 있습니다. set 커맨드는, 변수에 값을 대입합니다. set 커맨드로 값을 생략하고, 변수명의 처음에 $을 붙여주면 값을 참조할수 있습니다. unset 커맨드는, 변수를 메모리에서 삭제합니다.

set var 123
=>123
set var
=>123
set var abc
=>abc
puts stdout $var
=>abc
unset var

산술연산

expr 커맨드는, 정수나 부동소수점의 연산이나 비교를 행합니다. 삼각 함수나 난수등도 사용할수 있습니다.

expr 1 / 0
=>divide by zero
expr 10 + 0x10 + 010
=>34
expr 2.0 * asin(1.0)
=>3.14159265359
set i 1
=>1
incr i
=>2

커맨드의 치환

대괄호[]는, 대괄호내의 커맨드를 커맨드의 출력결과로 치환해줍니다.

set pi [expr 2.0 * asin(1.0)]
=>3.14159265359
set pi
=>3.14159265359

더블 쿼테이션(Double Quotation Mark)과 중괄호

더블 쿼테이션과 중괄호는, 여러개의 문자열을 하나의 덩어리로 묶어줍니다. 단 더블 쿼테이션 내에서 변수와 커맨드는 치환이 되지만, 중괄호 내에서는 치환이 되지 않습니다. 백슬래쉬(\) 사용한다면 ‘[’과 ‘$’의 치환기능을 무효화 시킬수 있습니다.

set var 123
=>123
puts "result = $var"
=>result = 123
puts {result = $var}
=>result = $var
puts "result = \$var"
=>result = $var
set var 123
=>123
puts "result = [pwd]"
=>result = C:/
puts {result = [pwd]}
=>result = [pwd]
puts "result = \[var]"
=>result = [var]

포맷(format)

scan과 format 커맨드는 ANSI C언어의 scan과 printf함수와 서식이 같습니다. %의 서식에 의하여 문자열을 포맷합니다.

scan "123.456" "%d.%d" a b
=>2
set a
=>123
set b
=456
format "%d.%d" $a $b
=>123.456

프로시져(Procedure)

proc 커맨드는, 0개이상의 인자를 받는 프로시져를 정의할수 있습니다. 프로시져 안에서 정의된 변수는, 프로시져안에서만 참조할수 있습니다. 프로시져 밖에서 변수를 참조하고 싶다면, 변수가 선언된 프로시져와 참조할 프로시져안에서 global로 변수를 선언하면 됩니다. 프로시져는, 디폴트로 인자나, 가변인자를 받는것도 가능합니다.

# 보통의 인자
set foo 3
=>3
proc add {a b} {
   global foo
   return [expr $a + $b + $foo]
}
add 1 2
=>6

# 참조형 인자와 디폴트 인자
proc plus {a {b 1}} {
   upvar $a r
   set r [expr $r + $b]
   return $r
}
set foo 1
=>1
plus foo
=>2
plus foo 2
=>4

# 가변 인자
proc sum {args} {
   set s 0
   foreach i $args {
      set s [expr $s + $i]
   }
   return $s
}
sum 1 2
=>3
sum 1 2 3
=> 6

주석(comment)

#로 시작하는 행은 주석의 행을 의미합니다. 스크립트 기술 도중 주석을 기술시에는 ;#가 되야합니다.

# 주석 1
# 주석 2 \
   주석 2의 계속
puts {Hello World} ; #주석 3
=>Hello World

제어문

if, for, foreach, while, switch 커맨드는 제어문으로 사용하는 커맨드입니다. if, for, while의 조건식은 expr 커맨드와 같이 사용할수 있습니다.

if, elseif, else문

set var 일
=>일
if {$var == "일"} {
   puts stdout 1
}
=>1
 
set var 이
=>이
if {$var == "일"} {
   puts stdout 1
} else {
   puts stdout 2
}
=>2
 
set var 삼
=>삼
if {$var == "일"} {
   puts stdout 1
} elseif {$var == "이"} {
   puts stdout 2
} else {
   puts stdout 3
}
=>3

for, foreach, while안에서는 continue, break 커맨드를 사용할수 있습니다.

for 문

for {set i 1} {$i <= 3} {incr i} {
   puts stdout $i
}
=>1
=>2
=>3
 
for {set i 1} {$i <= 5} {incr i} {
   if {$i < 3} {
      continue
   }
   puts stdout $i
}
=>3
=>4
=>5
 
for {set i 1} {$i <= 5} {incr i} {
   if {$i > 3} {
      break
   }
   puts stdout $i
}
=>1
=>2
=>3

while 문

set i 3
=>3
while {$i != 0} {
   puts stdout $i
   incr i -1
}
=>3
=>2
=>1

foreach 문

foreach i {A B C} {
   puts stdout $i
}
=>A
=>B
=>C
 
foreach {i j} {A B C D E F} {
   puts stdout "$i $j"
}
=> A B
=> C D
=> E F

switch 문

switch 사과 {
   사과    {puts 100}
   귤나무    {puts 80}
   바나나(banana)  {puts 30}
   default   {puts 모름}
}
=>100
 
switch 사과 {
   사과
      {puts 100}
   귤나무
      {puts 80}
   바나나
      {puts 30}
   default
      {puts 모름}
}
=>100
}

after커맨드는, 커맨드의 실행시간을 지연시키는 일을 합니다. after로 지정한 커맨드는 global scope에서 실행된다는것을 주의해야합니다.

after 문

after 1000 ;# 1초 기다리다가..
after 1000 "set a 1" ;# 1초후에 커맨드를 실행
=>after#0

catch 커맨드는, 에러를 캐치(catch)하는데 사용됩니다. 에러가 발생하면 1을 리턴시켜주고, 아니면 0을 리턴시켜줍니다.

catch 문

catch {expr 1+2} var
=>0
catch {expr 1*_} var
=>1
catch {expr 1/0} var
=>1
catch {error bug} var
=>1

에러처리

에러처리의 기술이 없다면, 에러발생시에 아래와 같은 창이 나타납니다.

에러처리는 잊지말고 꼭 처리해주어야 합니다.

proc foo1 {} {
   return -code error -errorcode 1 -errorinfo info message
}
 
proc foo2 {} {
   error message info 1
}
 
if [catch foo1] {
   puts "errorCode = $errorCode"
   puts "errorInfo = $errorInfo"
}
 
if [catch foo2] {
   puts "errorCode = $errorCode"
   puts "errorInfo = $errorInfo"
}

배열

배열의 첨자에 문자열을 사용할수 있습니다. parray커맨드는, 배열의 요소를 표시합니다.

set ary(사과) 100
=>100
set ary(귤나무) 80
=>80
set ary(바나나) 30
=>30
parray ary
=>ary(사과) = 100
=>ary(귤나무) = 80
=>ary(바나나) = 30
puts $ary(사과)
=>100
 
array set ary {
   사과 100
   귤나무 80
   바나나 30
}
parray ary
=>ary(사과) = 100
=>ary(귤나무) = 80
=>ary(바나나) = 30
puts $ary(사과)
=>100

리스트

lisp와 비슷한 리스트가 준비되어 있습니다.

set list { 사과 귤나무 바나나 }
=>사과 귤나무 바나나
lappend list 멜론
=>사과 귤나무 바나나 멜론
lindex $list 2
=>바나나
lsort $list
=>귤나무 사과 바나나 멜론

문자열

문자나 문자열을 위한 커맨드가 준비되어 있습니다.

if ![string compare -nocase "abc" "ABC"] {
   puts 같다
}
=>같다
string toupper "abc"
=>ABC
string length "xyz"
=>3
string length "귤나무"
=>3
split usr/local/bin /
=>usr local bin
join {usr local bin} /
=>usr/local/bin /
set str abc
=>abc
append str xyz
=>abcxyz

바이너리

물론 바이너리 문자도 지원합니다.

# ASCII to Binary
set bin [binary format i 0x12345678]
# Binary to ASCII
binary scan $bin H2H2H2H2 var1 var2 var3 var4
puts 0x$var4$var3$var2$var1
=>0x12345678

스크립트의 인자

스크립트 파일의 인자는, argc와 argv 변수로 알아낼수 있습니다.

set 스크립트이름 $argv0
set 인자의수 $argc
set1인자 [lindex $argv 0]
set2인자 [lindex $argv 1]
set3인자 [lindex $argv 2]

첨부 파일파일 크기
32.png7.25 KB