LogIn E-mail
설계이야기
[Tcl]Tool Command Language
# 12 JMJS    09.7.24 14:33

================================================================
Command Evaluation Step
================================================================
명령의 해석은 다음 순서로 일어나게 됩니다.

명령을 단어로 나누고, substitution을 합니다
명령을 실행합니다(evaluation/execution)
C에서 다음의 문장은

x = 4;
y = x + 10;
Tcl에서는 다음과 같이 써야 합니다
set x 4
set y [expr $x+10]
각 문장은 1번의 parsing/substitution과정을 거치게 되며, 여기서 다음과 같은 일이 일어납니다.

변수는 $으로 시작합니다.
은 안의 문장을 번역한 결과를 돌려줍니다(위 예 참고).
문장 뒤의 (backslash)는 현재 문장과 다음 문장을 하나로 여기도록 합니다. 단 { }으로 둘러싸인 경우에는 의미 없습니다.
{ }은 안의 문장을 substitution없이 넘겨줍니다. parser는 이 안의 문장을 하나의 단어로 여기게 됩니다.
" "안의 문장 안에서는 substitution이 일어납니다.

substitution은 일반적인 경우 한번밖에 일어나지 않습니다. 따라서 eval과 같이 parsing을 강제하는 명령을 제외하고는 번역은 한번만 일어난다고 생각하면 됩니다.

% set x [format {Earnings for July: $%.2f} $earnings]
Earnings for July: $1400.26

================================================================
주석
================================================================
주석문은 항상 행처음에 #으로 시작해야 합니다. 그렇지 않은 경우에는 #으로 시작해도 주석으로 인정하지 않습니다.

================================================================
변수
================================================================
변수의 대입은 set명령으로 합니다. Tcl에서는 변수의 타입이 없고, 타입이 없으므로 선언도 하지 않습니다. 각 프로시저 안의 변수는 따로 지정하지 않는 한 모두 지역변수입니다. proc문 안이 아니면 모두 stack level 0가 됩니다. 변수이름의 제한도 없으므로, 실제로 빈칸등이 들어간 변수이름도 가능합니다. 변수는 무조건 string이 들어가게 되지만, expr명령 등에서는 숫자가 아닌 것은 사용할 수 없습니다. 또한 struct과 같이 구조체를 선언할 수도 없습니다

set x 10
set abc "Hello World!"
set pi 3.14159
set "New York" 100
변수는 현 level이 끝날때까지의 수명을 가지고, unset명령으로 없앨 수 있습니다.

================================================================
배열
================================================================
Tcl에는 indexed array가 없고 오직 associative array만이 존재합니다. Multidimensional array도 없는데, 이것은 무식하게 해결할 수 있습니다.

set score(junker) 100
set score(bongbong) 50
set muld(3,5) 70
set muld($x,$y) 60
보통 variable substitution을 위해 $을 사용하는데, $은 그 다음에 영문자로 시작하여 영/숫자까지를 판별하는것에 주의합시다. 따라서 다음의 경우 { }으로 묶습니다.

.canvas configure -width ${size}m
incr과 append명령으로 ++과 strcat과 같은 효과를 얻을 수 있습니다.

% set x 5
% incr x
6
% set x "abc"
% append x "def"
abcdef

================================================================
수식
================================================================
일반적인 ANSI C오퍼레이터를 다 사용할 수 있다고 생각하면 됩니다. 다만 == <= >= !=은 별도명령 없이 string의 비교도 가능합니다. 비교문의 결과는 참이면 1, 거짓이면 0입니다. sin(x), cos(x)등의 수학함수도 쓸 수 있습니다.

% expr 3+5
8
% expr 6*7.3
43.8
% expr 6e4 * 7.91e+16
4.746e+21
% expr sin(60)
-0.304811

================================================================
리스트
================================================================
리스트는 단지 빈칸으로 연결된 단어의 집합니다. 때문에 단어 안에 빈칸이 들어갈 수 없는데, 이것은 { }으로 묶어서 해결할 수 있습니다.

% concat {a b c} {d e} f {g h i}
a b c d e f g h i
% list {a b c} {d e} f {g h i}
{a b c} {d e} f {g h i}
% llength {a b c}
3
% set x {a b {c d} e}
% linsert $x 2 X Y Z
a b X Y Z {c d} e
% lsearch $x d
-1
% lsearch $x e
3
% lsort {10 1 2}
1 10 2
% set y /usr/include/sys/types.h
/usr/include/sys/types.h
% split $y /
{} usr include sys types.h

================================================================
제어구조
================================================================
if {$x < 0} {
  set x 0
}
각 제어구조의 evaluation의 과정을 눈여겨 볼 필요가 있습니다. C와는 다른 형태를 취하는 것이, Tcl의 명령에는 block이 존재하지 않기 때문입니다. if의 경우에는 인수 두개(수식, body)만을 취할 뿐입니다(뒤에 elseif와 else를 사용할 수 있습니다) 따라서 비교인 수식부분도, 단순히 단어를 나누기 위한 수단으로 { }를 사용할 뿐입니다. 이는 다음 예에서 더 확실해집니다.

% set i 5
% while {$i>0} {
  puts -nonewline "$i "
  incr i -1
}
5 4 3 2 1 %
% set i 5
% while $i>0 {
  puts -nonewline "$i "
  incr i -1
}
5 4 3 2 1 0 -1 -2 -3 ...
{ }은 단순히 단어를 나눌 뿐 아니라 evaluation을 막아서 반복되는 제어구조에서도 새로운 variable substitution이 일어나도록 합니다.
for, foreach, switch도 비슷한 용법을 가지고 있습니다.

% for {set i 5} {$i>0} {incr i -1} {puts $i}
% foreach i {a b c} {puts $i}
% switch $x {
    a {incr t1}
    b {incr t2}
    c {incr t3}
}
eval은 인수들을 합하여 새로운 Tcl명령이 실행되도록 합니다.

% eval {set i 5}
5
% eval set i 5
5

================================================================
Procedure
================================================================
proc명령을 사용하여 새로운 함수를 Tcl스크립트로 만들 수 있습니다. 새로 만들어진 명령은 recursion으로도 사용할 수 있습니다. 보통 proc의 리턴값은 그 프로시저의 마지막 명령의 evalation값입니다. 그러나 이와 함께 return명령도 사용할 수 있습니다.
% proc plus {a b} {expr $a+$b}
% plus 3 5
8
앞에서 이야기한것처럼 모든 변수는 프로시저 내에서 지역변수이지만, 상위 변수를 global로 취급하려면 global명령을 써야 합니다.

global x y
이 경우 프로시저를 부른 프로시저의 a와 b를 global로 취급하며, 프로시저 내에서 a와 b변수는 지역변수가 아닌 전역변수로 취급하게 됩니다(C의 static과는 조금 다르다는 것에 주의하새요).

인수는 모두 call-by-value에 의해 호출되지만, 배열의 경우 C에서처럼 이름만 주는 것으로 배열을 읽을수는 없습니다. 따라서 이와 같은 경우에는 upvar명령을 사용하여 call-by-reference를 흉내내어야 합니다. Tcl에는 포인터 구조가 없습니다.

% proc parray name {
    upvar $name a
    foreach el [lsort [array names a]] {
      puts "$el = $a($el)"
    }
  }
% set info(age) 7
% set info(posision) "Vice President"
% parray info
age = 7
posision = Vice President
upvar명령은 단순히 이전단계의 프로시저의 변수를 쓸 수 있다는 것 외에 특정 level의 변수를 쓸 수 있다는 장점이 있습니다.

upvar #0 other x
또한 uplevel을 사용하여 새로운 제어구조를 만들어 낼 수 있습니다.

================================================================
문자열
================================================================
Tcl에서 한글을 쓸 수 있는가의 가능성에 대해서는, 대부분의 한글 메세지가 입력으로 들어가도 상관이 없지만, Tk에서 한글출력이 불가능하고(한글 Tk가 있다는 이야기는 들어본 적이 없기 때문에), 문자열 루틴에서의 오동작이 일어나기 때문에 그렇게 권장할만한 것은 아닙니다. 하지만 한글등의 8비트 메시지는 그대로 사용할 수 있습니다.

문자열 검색에는 두가지가 있습니다. glob와 regular expression이 있는데, glob는 shell의 방식이고, regexp는 grep(1)의 유닉스 표준에 의한 검색이 가능합니다.

% string match Tcl* "TclABC"
1
% regexp {([0-9]+) *([a-z]+)} "Walk 10 km" a b c
1
% set a
10 km
% set b
10
% set c
km
% regsub a ababa zz x
1
% set x
zzbaba
% format "%d is %c" 100 100
100 is d
% scan "16 units, 24.2% margin" "%d units, %f" a b
2
% set a
16
% set b
24.2
% string length "abc"
3
% string toupper "abc"
ABC
% string compare "abc" "def"
-1

================================================================
기타
================================================================
파일 I/O
파일 I/O은 POSIX표준의 파일관련 함수를 명령의 형태로 대부분 이용할 수 있습니다.

% set x [open abc r]
file4
% gets $x
Hello
% tell $x
6
% close $x
또한 file명령은 파일이름의 조작과 파일 정보를 얻을 수 있는 부명령들을 많이 갖고 있습니다.

set filename /usr/include/limits.h
set f [open $filename r]
while {[gets $f line] >= 0} {
puts $line
}
close $f

================================================================
프로세스
================================================================
exec명령으로 외부명령을 실행할 수 있고, >과 <<등의 리다이렉션명령으로 출력결과나 입력을 제어할 수 있습니다. |로 파이프도 사용할 수 있고, &를 사용하면 백그라운드 작업도 가능합니다.

% exec ls
#ht-tcl_tk.tex#  auto             ht-tcl_tk.dvi    ht-tcl_tk.tex
abc              ht-tcl_tk.aux    ht-tcl_tk.log    ht-tcl_tk.tex~
% exec cat abc | grep World
World
Hello World!
%

================================================================
history
================================================================
C쉘과 같이 !!등의 명령을 사용하여 이전 명령의 반복이 가능합니다.

 !!            이전명령을 반복합니다(history redo)
 !     해당명령을 반복합니다(history redo )
 ^old^new      이전명령의 old를 new로 바꾸어 실행합니다
               (history substitute old new)

게시물: 103 건, 현재: 1 / 2 쪽
번호 제       목 작성자 등록일 방문
106  arithmetic in a makefile, shell pwd export JMJS 17.9.8 597
105  Split and merge large files JMJS 16.3.21 573
104  [Makefile]random JMJS 14.12.5 871
100  윈도우7 용량부족 winsxs 폴더 최적화 JMJS 14.10.14 1775
99  [sh,csh]while loop JMJS 13.2.6 1954
98  hostname, hostid, /sbin/ifconfig eth0 JMJS 13.1.4 3717
97  [linux]fedora 16 gome-shell extension JMJS 12.3.12 1604
96  [linux]fedora 16 grub boot order change JMJS 12.3.10 1897
95  [linux]fedora Input Method,ibus,hangul JMJS 12.3.8 1588
94  [linux]audio,mp3,mplayer,gstreamer,vlc JMJS 12.3.7 2019
93  [sh].wrapper example JMJS 11.6.15 1731
92  [make]for loop JMJS 11.9.8 1580
91  [make]conditional expression JMJS 11.5.12 1499
90  [make]shell 실행 JMJS 11.3.9 1589
89  [wish]jplot JMJS 10.5.12 1262
88  yum JMJS 09.8.12 1320
87  [CYGWIN]X setup하기 JMJS 10.8.6 2454
86  [Make]Makefile Brief JMJS 10.8.6 1301
85  ldd /user/bin/xterm JMJS 09.4.24 1021
84  [HTML]어도비 SVG 뷰어와 HTML JMJS 09.4.24 1539
83  [DOS]DOS command JMJS 09.7.20 1242
82  [DOS]DOS command brief JMJS 07.2.21 1680
81  웹페이지 소스보기 JMJS 09.4.24 1224
80  [html]자동으로 글자색 바뀜 JMJS 07.1.10 1198
79  [html]복사, 드래그 금지 JMJS 07.1.10 1672
78  [csh]cshell에서 function 못쓴다네요 JMJS 11.3.17 1169
77  리눅스에서 i386,i586,i686, x86의 차이점 JMJS 06.10.16 1507
76  [CSH]$status JMJS 06.8.21 992
75  [sh]substr, read, until,IFS,for,dirname JMJS 14.12.19 1189
74  [sh]rgbview.sh . hello.sh JMJS 10.11.30 1103
73  automount - /etc/fstab JMJS 06.2.23 1132
72  lmutil.csh JMJS 05.11.8 1446
71  화일이름에 못오는 문자 JMJS 05.9.8 1198
70  /usr/ucb /usr/ccs JMJS 05.9.5 1113
69  Solaris Version JMJS 05.9.5 1337
68  /usr/ccs/bin/nm -x debpli.so JMJS 05.8.31 1592
67  tar, gzip, zcat, uncompress, mn(.a 파일보기) JMJS 13.1.6 1445
66  find . -name -print -exec perl JMJS 09.4.17 1412
65  pkgadd -d packagefile JMJS 05.5.9 1168
64  prstat JMJS 08.10.2 1395
63  vi 명령어, vim명령어 gvim JMJS 11.2.11 4065
62  multiple directory 에서 grep ? JMJS 04.5.31 1565
61  [csh].cshrc_axis JMJS 04.5.14 1463
60  [csh].cshrc_modelsim JMJS 04.5.14 1539
59  [csh].cshrc_cadence JMJS 04.5.14 1598
58  [csh].cshrc_novas JMJS 04.5.14 1477
57  [csh].cshrc_verisity JMJS 04.5.14 1828
56  lmgrd JMJS 09.6.22 2196
55  [csh]which case JMJS 04.5.14 1466
54  [bash]example 2 JMJS 04.5.12 1563
53  [bash]example 1 JMJS 04.5.12 1538
52  fedora 12에서 touchpad disable JMJS 11.1.17 1634
51  [Perl]한국어 인코딩 JMJS 04.1.16 2384
50  [Perl]HTML에서 기호 표시를 위한 문자치환 JMJS 04.1.5 9205
49  [csh]make awk JMJS 03.6.6 1796
48  [csh]wordsplit JMJS 03.6.6 1483
47  [csh]vi2 JMJS 03.6.6 1303
46  [csh]cat.csh JMJS 03.6.6 1391
45  [csh]chgword.csh JMJS 03.6.6 1283
44  [bash]password JMJS 11.3.9 1250
43  [Tcl]bi2int JMJS 02.11.29 1245
42  [PC]ask 검색창이 자꾸 뜬다면 JMJS 09.4.24 1666
41  [csh]backup_copyc.csh; foreach; continue JMJS 09.4.24 1419
40  uname, uname -s -r, uname -p, uname -a JMJS 09.4.24 1601
39  [tk]새 창 열고 닫기 예제 JMJS 09.4.24 11203
38  [sh]if [[ "$abc" == "abc" && "$bbc" == "bbc" ]]; ... JMJS 11.3.17 1303
37  [expect]expect_scp.exp JMJS 11.3.9 1403
36  ssh -x -l soc lion scp -r ... JMJS 11.3.9 1201
35  TclTk 배열 JMJS 09.7.20 1284
34  ./configure make make install JMJS 11.1.13 1203
33  [csh]diff JMJS 10.7.14 1283
32  tr abc 123 < file1 > file2 JMJS 11.4.11 1218
31  Installing RPMforge JMJS 10.2.8 1282
30  [태그]글자색이 사라짐 JMJS 09.4.24 1374
29  [태그]자동으로 글자색이 변함 JMJS 09.4.24 1357
28  글자태그 모음 JMJS 09.4.24 1465
27  색상명과 RGB값 표 JMJS 09.4.24 1506
26  RGB 색상표 JMJS 09.4.24 1659
25  한글특수문자표 JMJS 09.4.24 1288
24  bc -l JMJS 01.5.22 1217
23  file *,  od -xc *, cat * JMJS 01.3.28 1535
22  Linux Memo JMJS 09.7.20 1413
21  xterm -fn 10x20 & JMJS 12.3.7 1268
20  W/S Tip JMJS 09.4.29 1328
19  [awk]example JMJS 10.10.30 1533
18  [csh].cshrc JMJS 11.6.21 1843
17  stop & background job JMJS 00.11.14 1199
16  W/S shout down JMJS 00.11.14 1219
15  [sed]example JMJS 16.9.5 1559
14  [DOS]Memo JMJS 00.10.29 1316
13  [csh]리스트를 만들어 foreach로 처리할때 JMJS 00.10.7 4252
12  [Tcl]Tool Command Language JMJS 09.7.24 2405
11  [csh]vi.csh JMJS 00.6.27 1333
10  [csh]Check Process JMJS 00.6.27 1229
9  [csh]Get Character and get char without 'return' JMJS 10.2.8 1366
8  [csh]foreach SED JMJS 00.6.27 1579
7  [Window]오류보고 안 뜨게하는 방법 JMJS 09.9.23 1274
6  [csh]echo.csh JMJS 00.6.27 1433
5  set DDD = `date '+%y%m'` JMJS 00.6.27 1200
4  [SH]Advanced Bash-Scripting Guide JMJS 09.4.24 1159
[1] [2]