版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
楼主 |
发表于 2011-2-22 09:46
|
显示全部楼层
Tcl编程简介' c, w8 d/ O1 A7 U. F0 U) j8 V( c
简介1 U L' N8 K8 h2 C; L
Tcl是一种很通用的脚本语言,它几乎在所有的平台上都可以解释运行,功能强大,是tool
3 @1 h A) P% z: a Rcommand language的缩写,发音为“tickle”,实际上包含两个部分:一个语言和一个库。
. R; z6 O" ?5 D z" z. _; t首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调
* F; E- E7 Z% o) M6 P, q8 z试器和shell。它有一个简单的语法和很强可扩充性,Tcl可以创建新的过程以增强其内建4 |$ m" Y. Z$ Q
命令的能力。
1 \9 R* l. y$ \其次,Tcl是一个库包,可以被嵌入应用程序,Tcl的库包含了一个分析器、用于执行内建
! R( i4 E. G4 v! v1 l命令的例程和可以使你扩充(定义新的过程)的库函数。应用程序可以产生Tcl命令并执行,# u1 F: m* G9 a8 s
命令可以由用户产生,也可以从用户接口的一个输入中读取(按钮或菜单等)。但Tcl库收6 _* [: k2 L3 T' k1 _( Z) q+ Y
到命令后将它分解并执行内建的命令,经常会产生递归的调用。
/ J5 O' h. |: Q% i! F3 t下面简单介绍以下txl的语法规则:8 d @2 w3 B5 k1 X/ m
解释器& w$ a* b0 E; ^/ ^, x7 C
在tcl的数据结构中的核心是Tcl_Interp.一个解释器包含了一套命令,一组变量和一些用0 G/ Q) a, U7 i! d! m# y
于描述状态的东西。每一个Tcl命令是在特定的Tcl_Interp中运行的,基于Tcl的应用程
8 @1 L, @2 c: K. T8 T0 Y序可同时拥有几个Tcl_Interp。Tcl_Interp是一个轻量级的结构,可以快速的新建和删除。
+ U- x R# i6 M数据类型
8 f, ]- N0 O( z" d1 Z7 ITcl只支持一种数据结构:字符串(string)。所有的命令,命令的所有的参数,命令的结7 c& O8 j! P7 w: |3 k- S1 p6 d9 B c" z% w
果,所有的变量都是字符串。请牢记这一点,所有的东西都是字符串,是它较有特点的方面。" \- M& s7 s: ?4 e( k+ w3 p
字符串有三种形式:命令(command),表达式(expresion)和表(list)。1 k; D# v4 _ e. ^' d- F
Basic Command Syntax 基本语法
# i/ f! K% h$ |4 YTcl有类似于shell和lisp的语法,当然也有许多的不同。一条Tcl的命令串包含了一条或4 |4 A& L$ A% H0 B2 Y; w
多条命令用换行符或分号来隔开,而每一条命令包含了一个域(field)的集合,域使用空白
% `' r" L" n0 @( j分开的,第一个域是一个命令的名字,其它的是作为参数来传给它。& F+ Z. r5 T& V& u( q. [
例如:set a 22 //相当于C中的 a=22 a是一个变量
- j% x3 c* u" C; _( n这条命令分为三个域:1: set 2: a 3:22 set使用于设置变量的值的命令,a、20作为* }; ?; O# `$ Q! R2 D
参数来传给它,a使它要操作的变量名,22是要付给的a值。! h" J7 [( `" p" g! I k, Q4 V: @
Tcl的命令名可以是内置的命令也可以是用户建的新命令,如果是用户用户建的新命令应用
% _6 U* w0 q3 A2 H' I* u2 w, b程序中用函数Tcl_CreateCommand来创建。所有的参数作为字符串来传递,命令自己会按其6 Q1 p q5 B2 D, }+ U
所需来解释的参数的。命令的名字必须被打全,但Tcl解释器找不到一同名的命令时会用. ~# g3 o3 V! A* x
unknown命令来代替。
0 \3 e: F4 [1 N* y2 W' o在很多场合下,unknown会在库目录中搜寻,找到一个的话,会自动生成一个Tcl命令并调- D/ W% [; A) I" X% B) i1 y
用它。unknown经常完成缩略的命令名的执行。但最好不要使用。
4 I$ c5 C% V- B V注释
! v: B% s9 X5 o3 N$ t0 c6 P和shell很象,第一个字母是"#"的Tcl字符串是注释。2 s* p+ K8 u1 E3 X
其他细节规则
3 h/ T+ C. W5 g: w6 k4 ZGrouping arguments with double-quotes 用双引号来集群参数,目的使用有空白的参数。
1 I# s& ^* N* ?( d% W( T例如:, q# h q3 y: B8 x& m; W
set a "this string contains whitespace"
) r9 V' e4 p. m( [如够一个参数一双引号来开始,该参数会一直到下一个双引号才结束。其中可以有换行符和9 X' O" v& Y8 O2 M6 \/ |5 \
分号。
2 Z* l- E& n) P7 MVariable substitution with $ 用美元符进行变量替换说白了就是引用该变量。
4 D9 _! ~& c" J9 U- F5 u4 f& _例如:. V* b C! F$ j! b
set a hello
+ p; a) \4 ^& I6 X7 R2 \set b $a // b = "hello"实际上传给set命令的参数//是b,"hello"
0 B- i- a/ N! K0 Gset c a // b = "a"
9 Y* O2 l6 `2 @. B9 m2 OCommand substitution with brackets 命令子替换(用方括号)$ l2 X$ \- u" m+ Q% d
例如:/ e8 X, o" `* R5 G5 v2 E' ~
set a [set b "hello"]; p9 J h6 U! z$ j5 L, n
实现执行 set b "hello" 并用其结果来替换源命令中的方括号部分,产生一条新命令
$ L+ S6 ]5 v# n+ Z0 Q/ j9 tset a "hello" //"hello" 为set b "hello"的返/回值最终的结果是b="hello" a="hello"
3 N$ J( [; ?1 N- M- H' F0 u当命令的一个子域以方括号开始以方括号结束,表示要进行一个命令子替换。并执行该子命, v8 L0 }1 S- m) K4 u
令,用其结果来替换原命令中的方括号部分。方括号中的部分都被视为Tcl命令。
- p9 u9 ^# X$ H; p5 i5 V4 C如下一个复杂一点的例子:
0 l! Y8 ~; I Xset a xyz[set b "abc"].[set c "def"]
( b4 L3 L+ `: w8 E2 k, u//return xyzabcdef) w1 ^: \3 X8 K6 s5 D
Backslash substitution 转移符替换5 e0 t. G7 K) `
转移符时间不可打印字符或由它数意义的字符插入进来。这一概念与C语言中的一样。' M" ?( R H' A; F1 K2 |
Backspace (0x8).
4 |: h% D. o9 d/ Q0 U+ W" c7 Qf Form feed (0xc).1 M- O8 [6 z8 t; J9 X
Newline (0xa).
) n6 b2 ]. \0 M6 O, n$ o+ QCarriage-return (0xd).
+ k- q0 N2 r$ j% y c# I/ PTab (0x9).
/ G: K( k0 j r0 c* ev Vertical tab (0xb)." p. W9 Y, k/ ~ N8 R1 [
{ Left brace (`{").2 A3 B v+ H0 M0 G7 I
} Right brace (`}").
$ V: K: i/ t+ F$ M[ Open bracket (`[").
! U1 B9 ^8 K# `' I9 Z* f3 Q: v- j] Close bracket (`]").0 j d: [+ g9 G3 u# T
$ Dollar sign (`$").- v2 A, h, r- E; G6 {% G) y) j
sp Space (` "): does not terminate argument.
9 h0 {5 H8 [* b8 } q; x3 |; Semicolon: does not terminate command.6 `7 ~. a- f/ X4 }
" Double-quote.; I% v9 R. u* {2 n8 }0 U6 n* y6 ~
Grouping arguments with braces 用花扩括号来集群参数,用花扩括号来集群参数与用双1 s n& ~" z/ h) z5 e
引号来集群参数的区别在于:用花扩括号来集群参数其中的三种上述的子替换不被执行。而1 W: l, v1 x# ]1 x
且可以嵌套。
0 Z9 `7 R& m2 t" x' V. {( W1 g- p例如:
3 R* h! U x8 }5 _" a$ I9 o7 Nset a {xyz a {b c d}} //set收到俩个参数 a "xyz a {b//c d}"6 w) z( A7 m% c* k
eval {' ?0 Y: Q3 n1 E, ^5 @- [8 A
set a 22
, U1 U& O; O8 J% ?- F1 U% f- dset b 339 S, ?1 G7 z0 E7 d; ?6 q2 Y
}//eval收到一个参数 "set a 22) h9 Z& x, l5 U8 [( O. u; ~: J
set b 33"% I" U+ c0 N. h+ [0 V. I
命令综述. y) g' }* U6 N! v, n
1.一个命令就是一个字符串(string)。* C: H8 `, a+ x7 Z' D6 w' W
2.命令是用换行符或分号来分隔的。
1 G. X, Q* l$ O, n3.一个命令由许多的域组成。第一个于是命令名,其它的域作为参数来传递。# x1 }! q. ~7 G* O
4.域通常是有空白(Tab横向制表健 Space空格)来分开的。* Y( J; S- m8 l. X2 O* }( r* u2 O% Q
5.双引号可以使一个参数包括换行符或分号。三种子替换仍然发生。
6 s6 J6 A% t' g6.花括号类似于双引号,只是不进行三总体换。
4 B; s( W3 F' f8 ]7.系统只进行一层子替换,机制替换的结果不会再去做子替换。而且子替换可以在任何一个
% U% @: V+ C' G7 j! a域进行。1 s: {' n+ I- I0 f7 A
8.如果第一个非控字符是`#", 这一行的所有东西都是注释。
/ F6 p8 |" v7 u, {2 T, K1 K# Q+ E表达式8 w9 A. r; l$ G, F, E0 x
对字符串的一种解释是表达式。几个命令将其参数按表达式处理,如:expr、for 和 if,并& |3 _& w ~: L( @
调用Tcl表达式处理器(Tcl_ExprLong,Tcl_ExprBoolean等)来处理它们。其中的运算符与C v& h) g9 v$ I' j% ~
语言的很相似。
- l/ n5 a- g# ]" W: v4 x( ^! 逻辑非$ N! r7 g" O: w. a' k
* / % + - 加减乘除余数
$ D/ b4 ]4 r' b" x<< >> 左移 右移 只能用于整数。
8 G$ b& Y1 q* M6 c$ A< > <= >= == != 逻辑比较" i8 c* ^4 [8 I$ a
& ^ | 位运算 和 异或 或: a3 r/ F3 H5 e$ l
&& || 逻辑"和" "或": ?5 X* L$ b8 Y, w( _8 c
x ? y : z If-then-else 与c的一样# k8 d. a) G8 j: s) j
Tcl 中的逻辑真为1,逻辑假为0。
8 Q& f+ K# F( N. H! ]. {一些例子:
6 e/ ^8 {: l5 @! S8 n( c& S5 / 4.0- h1 v, e: Q+ D
5 / ( [string length "abcd"] + 0.0 ), X7 \: d% w* t i
---------------------- ---1 t+ k2 a/ I" z3 X. \ G2 j- Y
计算字符串的长度 转化为浮点数来计算- h' e; x& U1 n
"0x03" > "2"2 o0 D5 ^$ U: J/ ]( D) U. a
"0y" < "0x12"
+ `: y( R. R% ~ ~8 h3 ]都返回 1" C: b+ x" L+ p ?# h, C; x
set a 1
0 m9 l2 W! i1 y; E1 g5 qexpr $a+2
- E& v' F- Q. d, n& |2 d/ Iexpr 1+2
5 `: |" N& T2 M7 J: ?( Q% q都返回 3
- C2 ]5 W i/ E, [2 c2 Z( |% D列表% p$ J/ q4 Q; L7 e$ U# r0 ^
字符串的另一种解释为列表。一个列表是类似于结果的一个字符串包含了用空白分开的很多, T1 C# n' i, z' A& ~
域。例如 "Al Sue Anne John" 是一个有四个元素的例表,在列表中换行父被视为分隔符。2 r/ y* E/ q4 h7 \1 b- l' r) `
例如:' v' \ X6 K5 r4 @1 R0 K3 [6 d. ]3 j
b c {d e {f g h}} 是一个有三个元素的列表 b 、c 和 {d e {f g h}}。( V8 U# d7 d& F* x) p' x
Tcl的命令 concat, foreach, lappend, lindex, linsert,list, llength,lrange,lrepla% Y7 l: }* M! J, z, p* i
ce, lsearch, 和 lsort 可以使你对列表操作。+ z6 u8 F4 H- R5 m
正则表达式
) |" Y' |" Q; T; dTcl提供了两个用于正则表达式的命令 regexp 和 regsub。这里的正则表达式实际上是扩& `# p5 _& k) H) O/ H* a: [
展的正则表达式,与 egrep 相一致。, B6 ~3 n4 ~6 a; q+ M: L4 H, x! P
支持 ^ $ . + ? > < () | []0 Z* E' `+ l+ S( O4 `/ r
命令结果
, ]) j5 f5 o; E7 U8 ^3 S每一条命令有俩个结果:一个退出值和一个字符串。退出值标志着命令是否正确执行,字符1 \ N v5 }" x. e
串给出附加信息。有效的返回制定议在`tcl.h", 如下:( ?& M! x2 O8 j; K' R) ]
TCL_OK
7 ]2 A- Q4 k" v, h/ F( z. e) Y: [命令正确执行,字符串给出了命令的返回值。) f" G- o; j" ^4 M0 c% h. `
TCL_ERROR
2 g2 l( J A( Z% ~# @表示有一个错误发生,字符串给出了错误的描述。全局变量 errorInfo 包含了人类可读的, @; U! ?6 b5 r1 N; o+ R4 K
错误描述,全局变量errorCode 机器使用的错误信息。
' s5 j* Y& c0 p, s2 M6 c: iTCL_RETURN
5 j x; P/ K: ~4 u* B' c表示return命令被调用,当前命令(通常是一个函数)须立刻返回,字符串包含了返回值。
' k" P& I0 s' D" S9 M; @3 ~* mTCL_BREAK& ^3 `9 h& N: s4 v) ]
表示break已经被调用,最近的循环必须立刻返回并跳出。字符串应该是空的。" _! ~& B2 F$ l6 K9 E
TCL_CONTINUE
: c5 m# W0 V. V) Z2 |表示continue已经被调用,最近的循环必须立刻返回不跳出。字符串应该是空的。
) C7 u8 d% y/ wTcl编程者一般需要关心退出值。当Tcl解释器发现错误发生后会立刻停止执行。
9 j8 K; ?. V- @/ A7 TProcedures 函数3 I, H/ C$ H, E4 F
Tcl允许通过proc命令来扩充命令(定义新命令),定义后可以向其它的内建命令一样使用。
. m' k# r3 S, N7 e# g. M2 y例如:
& }9 ~% N- D0 r, Z, v0 Dproc pf {str} {
$ p; @. O) m* z8 [* Cputs $str w1 U5 x, o7 I; {* k& S4 C
}
! h4 X7 s0 R# m; m. apf "hello world"' f7 y; @ e" P" B4 H
这里有一个初学者不注意的地方,上述的定义一定要写成那样子。而不能向下面那样写:4 ~% g V/ L: x4 H$ l! I" p
proc pf {str}
$ l: f1 H) m8 e{
" K& I* @* Z3 zputs $str
% H+ Q) d) E5 V6 U3 M# w9 |}# f# Z/ h# C* O
因为proc实际上也只不过是一条命令,是一换行符或分号来结束的,用集群参数来传递函
# \" c7 S0 I9 ^9 O. H数体。proc的定义如下:
9 l2 m. |/ g: P! w% hproc name args tclcommand( l( m( R' B! M/ ~" w+ o, u
Variables: scalars and arrays 变量:标量和向量(即数组)
* z" r" Y, N- D9 |向量就是数组,而标量是没有下标的变量。4 E/ P. c* F/ Y0 Z2 w; Q
我们用C来类比:+ y2 h% W, ^4 U$ h
int i; // i 是标量
, g8 q. b8 G1 o. qint j[10]; // j 是向量, P3 P. o& b! O& |5 r1 y- b! B3 R
变量不需要定义,使用的时候会自动的被创建。Tcl支持两种变量:标量和向量,举个例子
, \ A V. | G. }& n来说明吧:
2 b6 | Q) U ?0 k. n1 \. pset i 100$ j6 r4 `% J) U% E
set j(0) 10
8 C0 A8 P% O* p% q! Xset k(1,3) 201 K& D) v' P2 b8 c$ T
i是标量,j是向量。; K6 J0 R4 C! e3 }
引用的时候:
( Q K6 ]& ?0 G+ v) L, i3 ^$i
6 Z" u4 ?: k+ P. A7 i5 O$j(0)
7 b; s) q F, m6 x9 a$k(1,3)7 E3 i. }- S6 }6 W3 r; R
Tcl 内置命令
; m$ I7 W; c v内置的命令) g- G \& \, {+ T% V) w
Tcl提供了下面描述的内置函数。其中: ... 表示参数不定,具体有:/ R" t4 ?0 y2 ]+ J1 Q6 f9 r" `. f7 U O
append命令:
+ z( s& J/ X0 `3 A2 Y( j, Xappend varName value
u0 {& ~( P' C* }- Yappend varName value value value ...8 }" g; N% h9 W' | x' d T3 Y
将那一大堆value附加到varName后面。如果变量不存在,会新建一个。, d2 Z% s' T+ P7 ^7 m; ^1 d1 c
例子:
" f8 ]4 U, N. b6 M- nset i "aaa"6 B# c/ l9 R8 T0 s
append i "bbb" "ccc"1 N/ e5 \3 i1 _3 V
//i = aaabbbccc
' @# u$ M( [) H5 c% @* d: c2 T, Warray命令:
$ I b7 Y; n) n2 ^. R+ C$ darray subcommand arrayName
, m3 p) G& r# q5 b* F, ~' \array subcommand arrayName arg ...
F& T. w7 B) s0 s3 {这是一组用于向量操作的命令。第二个参数是子命令名。
$ h8 Q. L- M* m1 u假设:
5 H& y0 v( G7 j- r5 Sset a(1) 1111
( d9 S' c5 w' k: ?/ Uset a(2) 2222
- [5 o1 |. f, ?5 V) e0 Tset a(three) 3333* h5 W- d6 w, C7 I/ @
以下均以它为例子(tclsh在中运行)。8 L0 f( _! v0 b+ e, Q
array names arrayName3 o( X8 M0 n. ~2 c
返回一个数组元素名字的列表。
9 L' h: n( ]1 m: t. @ dtclsh>array names a
6 M4 Y! K4 b4 @6 e! Z! k0 r+ Z1 2 three
* V8 R% w: h0 b$ S. ]5 X+ h4 Carray size arrayName% Z+ W0 [$ r3 S. N) \/ F, ]
返回数组的元素个数。# M' ]" I2 \( {4 p4 \( Y/ [4 x5 m( q
tclsh>array size a
; J7 P$ a' w$ m3
t% Y2 X0 X" {) Q! u; d& J! A下面是用于遍历的命令7 P! N4 |" [( k6 c+ e$ o
arrry startsearch arrayName
4 {% J( p. m' j4 j; A; I3 e初始化一次遍历,返回一个遍历标示(searchId)在下面的命令是中使用。
& v. K4 a* `$ ^/ S* K6 T9 s8 narray nextelement arrayName searchId+ ]/ ]) R9 i: `6 x) o
返回下一个数组中的元素。如果没有返回一个空串。# A5 O. Z, t# v2 x) A
array anymore arrayName searchId
8 |) [8 R" `- o. s7 ?返回 1 表示还有更多的元素。0 表示没有了。& O. Y. @7 T" s" V8 s4 v
array donesearch arrayName searchId
* Z4 A1 Q) x/ J9 W$ Q结束该次遍历。
, V M Q) @! O' Marray nextelement arrayName searchId, i v/ c& W9 D: c, w8 C; {+ i0 L
返回下一个元素。) p! z; H2 J" o& e* T
tclsh>array startsearch a# i+ g5 X: O8 {( M7 z: ]
s-1-a0 X/ u% n% T& v" K
tclsh>array nextelement a s-1-a
. g# U# g: \5 e1111
* j5 C' M3 `: Ztclsh>array nextelement a s-1-a
+ X6 g+ z! { x5 R1 }* [+ v2222
4 X1 ^4 Q+ g3 v8 ]tclsh>array anymore a s-1-a
; A- K8 E) w* ]2 T+ ?5 [* P1
T0 P/ Z7 p& { ltclsh?array nextelement a s-1-a# i& t# ?5 n" p1 S4 C# |% ^* z$ _
3333
& X, Q; b/ a) Ytclsh>array donesearch a s-1-a
) ~' G; G$ R+ O0 ^( ?注意可以同时并发多个遍历。( @0 a, g J2 F& a( Y
break命令3 }9 l1 S! a1 }: h$ n; W$ l
break
0 ]* v9 U4 i! k* j3 S跳出最近的循环。& ?/ X6 E0 ^% {/ }0 N9 u! o
case string in patList body ...! ~# m5 L' v6 S# t6 ]7 F
case string patList body ...
* X. E% {' F- b2 Q' V% X, `case string in {patList body ...}
) [3 W8 {/ A5 `3 j1 r. tcase string {patList body ...}/ K3 g7 V# \1 X) `6 r4 h: R9 m, z
分支跳转。( f+ k; Q- {( m7 K& j B) c
例如:- T* z) Y! g( B! q
case abc in {a b} {puts 1} default {puts 2} a* {puts 3}, U F# y( G2 [% K8 [4 \
return 3.
3 B4 ^$ q1 U9 n& y9 ycase a in {/ i; k* }' b9 C& e; h
{a b} {format 1}
) L+ Y* d3 t2 N9 ^3 Y* pdefault {format 2}
+ P% ~" x. N' @2 _8 H9 {+ ea* {format 3}
- j' v8 H5 `3 o+ y; J}
/ c1 j* r/ n h7 M' ~7 H n b4 oreturns 1.
, M+ |$ P# X5 g2 P$ h+ ncase xyz {
; D9 C: K8 y+ q/ ~{a b}& j: w4 ?7 r- _3 [: B
{format 1}, i+ F% R, A# `, j4 x
default6 b% b( {% Y r+ j( c8 I
{format 2}
T1 s& G- u: V/ Ma* d, D5 F, d2 L+ Q9 }
{format 3}
2 T* T, {3 S; _! }' l}
J& t$ Q6 u" L& `5 s& W3 vreturns 2.
" e& a& R5 X4 H2 P( v! m6 q注意default不可以放在第一位。支持shell文件名风格的匹配符。+ j/ f4 E" ?! J0 e8 x* E7 c
catch 命令2 k d3 O/ M+ T4 y. W: Q
catch command varName
: x0 }7 b2 ^' x6 L" D用于阻止由于错误而导致中断执行。执行command,每次都返回TCL_OK,无论是否有错误发
1 P7 a1 ?& o6 v6 i生。如有错误发生返回1,反之返回0。如果给了varName这被置为错误信息。注意varName
( g# |, C+ q) W: B) K' F; W是已经存在的变量。
' p" h" [6 l# W5 z, mcd 命令(如shell)4 C0 c$ Y( q# C
cd dirName% m4 S7 a: b' s- C
转换当前工作目录。如dirName未给出则转入home目录。$ y! ]5 z9 a F1 j* i
close fileId
! G1 \9 e7 n7 \. j, t! Z7 x关闭文件描述符。
! S/ V" v G) Z3 Oconcat arg ...
* K' v# F; o% w" X, I. C将参数连接产生一个表。8 ?: ?% l4 W3 i3 D) z; w
concat a b {c d e} {f {g h}}5 e) f, i3 R2 W6 i N; \
return `a b c d e f {g h}"
' a. V7 B% x7 [/ j0 L2 Vcontinue& E0 W0 X) }4 z1 p! b. w3 J: O
结束该次循环并继续循环。& d1 O W Z/ S: r
eof fileId
" P6 I8 o# Y5 ~- P7 ~0 D! P如fileId以结束 返回1,反之返回 0。. G1 y6 m6 C4 Y- J
Error命令
- C( Q' E9 U( M4 F( M8 b' `error message# u# A/ U( [9 h3 y6 M
error message info3 ]1 B' V! A6 {
error message info code
5 O4 R8 }5 b7 Z6 G8 V: G$ ]返回一个错误,引起解释器停止运行。info用于初始化全局变量errorInfo。code被付给6 z5 G" F1 m& H0 P* ]
errorCode。
) {$ f4 |8 C( \4 f4 e, Deval arg ...: [' U. e& b [8 u, x" v
将所有的参数连起来作为命令语句来执行。
1 x O8 `. C1 S; j+ \/ yexec arg ...0 `. O6 ^" f3 j: a- W- K6 P
仿佛是在shell下执行一条命令。
2 U. W8 z0 W4 }$ N( W& {) p+ w5 C7 O9 mexec ls --color! g F6 }+ E, ^6 g
exec cat /etc/passwd > /tmp/a
- W3 C' q' F; f2 Q& k; hexit
. u4 ]" t Y# m3 Uexit returnCode
" G! [1 u) \, N# Q# b. M中断执行。
( B+ R. O# L3 I1 ?expr arg% g$ U; G: {, k" e7 \# [
处理表达式。
7 `: p# g3 P! x6 kset a [expr 1+1]
0 [% ?* Z% S. r- W) F# d1 o//a=2! Y3 M( K* b6 H0 \8 U% X3 a0 d
file subcommand name5 ?/ `9 k6 b% _* c
一组用于文件处理的命令。
. Q3 t* [+ } `7 N* b+ ^file subcommand name arg .../ t* C1 `7 ^4 ]7 b% z
file atime name
4 r) v0 ^+ Y" M: f. k2 ^返回文件的最近存取时间。. A0 S6 c! |, p/ |6 F- w l/ X
file dirname name
- z9 @/ g) S3 f4 _$ g% T' l# F& x返回name所描述的文件名的目录部分。) ]( W9 o9 X, \6 b
file executable name
7 z5 e( p& X: A! K; H返回文件是否可被执行。
2 m: e! @! S1 J3 ^' c" Mfile exists name
4 B/ j0 {9 ^$ n" @9 a* @1 W( W- J返回1 表示文件存在,0 表示文件不存在。, m. g* J0 Q) S* |0 T
file extension name
b* g8 L8 Z) ?. Q/ N$ w返回文件的扩展名。
% s6 K0 [- u" d5 a9 y( V- tfile isdirectory name
" @, z( k( `1 Z; F, ~/ L判断是否为目录。1 n" Q$ }' T3 b+ X
file isfile name
: H5 H7 o& s1 K判断是否为文件。
6 M4 f3 J! G, C1 P8 R" Hfile lstat name varName
3 J. x7 Z* I8 S. J) ~5 u5 w以数组形式返回。执行lstat系统函数。存储在varName。3 x1 r: X: o* n
file mtime name" v# x! V$ B9 o( ^
文件的最近修改时间。
* E& v" M, U/ l4 p1 ~file owned name
' Y+ \/ X; j% Z' [( |( |判断文件是否属于你。- p: X( U; z* Z" q5 m
file readable name0 f4 B. _5 R5 N) w! K" H
判断文件是否可读。
2 t) ~3 t. h1 f, Y- w! gfile readlink name2 v7 G: G7 [ R0 B; ]
都出符号连接的真正的文件名。& ^* [5 k, @3 n1 M- ]
file rootname name; s6 W: K# J) L% U1 A
返回不包括最后一个点的字符串。0 u( h8 u3 B/ {0 v
file size name9 X! V+ B0 n7 p& g/ R3 `; K
返回文件的大小。. H0 R" _( a/ Y3 X4 E
file stat name varName
/ Y: A# B6 o: B调用stat内和调用,以数组形式存在varName中。
( X. ]. G( Q4 Q1 K% zfile tail name! w* y; B# \! I
返回最后一个斜线以后的部分。
5 M3 a4 b7 `3 p6 _4 H" D) ?file type name
7 ?4 \5 q0 i0 t! o" E" @返回文件类型file, directory, characterSpecial,
& X# |# d! s b$ j$ f+ P6 ~ \" EblockSpecial, fifo, link, 或/ `' j( [, c7 Y6 \/ c
socket。6 d# a2 S& @" Q0 q+ N
file writable name
% M8 v+ m L- t0 b! `5 [" k判断文件是否可写。
4 x4 v4 O; k8 d3 N4 p1 Uflush fileId
L/ O1 d7 U. x( \1 x/ i. f* I立即处理由fileId描述的文件缓冲区。
7 w- _- K7 ]7 u9 a. N3 Yfor start test next body" E/ M9 o5 j6 ^
for循环。同C总的一样。
) z( l& a5 Y9 K1 d k9 Y# w1 Rfor {set i 1} {$i < 10} {incr i} {puts $i}* x6 _, A/ K' G" e
foreach varname list body9 J9 _0 V2 A9 a9 a! q( e6 [% F9 E
类似于C Shell总的foreach或bash中的for..in...
* T) B" V; N; B8 v) r# Zformat formatString
6 {9 F; n. U& V: e, kformat formatString arg ...& l9 E/ d8 K! u# j7 p
格式化输出,类似于C中的sprintf。( X- [* K( V7 d. h' L
set a [format "%s %d" hello 100]
. g# A! s$ u. d0 {//a="hello 100"
( t. H8 N/ D4 g. ]& @$ Ngets fileId
9 R$ I& @3 X' _gets fileId varName
& F# i9 T/ E2 m9 i& \从文件中读出一行。3 t6 E& O/ d2 I- n Y: G
set f [open /etc/passwd r]/ _6 c4 [0 Q) }6 t. U
gets $f, A* u9 a' Y5 q2 ~1 K
glob filename ...; o A0 Z5 ]$ H0 u [1 o* x
glob -nocomplain filename ...0 C0 Z5 N0 t* i7 S" e
使用C Shell风格的文件名通配规则,对filename进行扩展。
3 ^4 T5 f; f8 o( h9 Y0 ?ls /tmp/ O8 E% p+ v w6 N3 K% k4 o7 D
a b c0 d- @3 H! i# O6 w2 A5 k2 C
tclsh>glob /tmp/*
0 |2 B5 W A+ f& v! `a b c( @$ |0 C; M9 G; ~- w. K
当加上参数 -nocomplain 时,如文件列表为空则发生一个错误。
; T, b" `% ?$ J7 ]' l0 pglobal varname ...9 t6 i4 Q/ V$ M. p
定义全局变量。9 n5 o. k/ v1 Y; g
if test trueBody
7 C, u2 v7 Q% \. a0 I# ^if test trueBody falseBody
4 e; |7 q/ g0 @3 X7 n! lif test then trueBody$ P* B' U- H; ]5 c4 K! | V
if test then trueBody else falseBody
7 \9 ~! w! _* N: E条件判断,实在没什么说的。
C# s0 i1 ^9 b% @incr varName
( j& w6 n" H6 l8 o+ I; Rincr varName increment
p5 N" _; i- b- l! y& u0 d+ f) v如果没有incremnet,将varName加一,反之将varName加上increment。
; e( l8 v, A2 E! @; iset i 10
. y* P1 \* V2 H9 @$ Iincr i
3 w; Z, s$ x* n6 f6 j7 @7 q; t, o//i=11
, y* a7 z5 b7 a; hincr i 10
) U$ T' {( I' N$ U. f) W% C//i=210 m# a+ s: G, u [0 B
info subcommand
% Z: {/ f" |0 ~: o7 d: Ginfo subcommand arg ...0 L) \, `6 x+ V; U1 f5 h) d! o& n. ]
取得当前的Tcl解释器的状态信息。& M* Q4 T6 w: T. L; s; r
info args procname- y+ @/ h: b. T: D" \
返回由procname指定的命令(你自己创建的)的参数列表。如:
; r ? k- X7 b4 C" J( V" {7 R$ qproc ff { a b c } {puts haha}
6 U# Y" {/ v- qinfo args ff
- ~8 H) n7 e7 j; S. T* |//return "a b c"
/ ?5 h% e3 u$ `info body procname% I" U- }# B6 Y2 |5 j+ K
返回由procname指定的命令(你自己创建的)的函数体。如:
W V) }3 L8 O; U8 ]* @1 Zproc ff { a b c } {puts haha}" ~# r1 g0 _3 I
info body ff1 P) k8 H& c5 y
//return "puts haha" % ?4 ^) ` w$ _; }4 O% F
info cmdcount. @# K# N" R0 n* {
返回当前的解释器已经执行的命令的个数。( [4 p; O# S: v; L
info commands2 c; E. q. n* D" l. q+ V. X8 a
info commands pattern/ V4 w. N& q: g- R6 R
如不给出模式,返回所有的命令的列表,内建和自建的。模式是用C Shell匹配风格写成的。
+ d7 N$ h( L" i! Dinfo complete command/ `7 Z4 Q6 `1 C: t$ b3 U, G
检查名是否完全,有无错误。' _* y' i% `! D4 _: c/ i3 x
info default procname arg varname8 K' Z0 g6 [2 a: C
procname的参数arg,是否有缺省值。
; U Q; X/ B, I; z# c/ e: {1 Vinfo exists varName6 r1 ^4 b+ J* i" u U
判断是否存在该变量。) \' k( w7 n5 s# R
info globals
" V# h8 z3 {0 ]( F% G4 u- [info globals pattern
( t2 j# {+ d+ m5 R返回全局变量的列表,模式同样是用C Shell风格写成的。
, O' C c; Q% _* A( Qinfo hostname
; u* x: ^4 L/ l! \* ?返回主机名。
, t6 t8 o$ z3 ^# x/ }info level8 ?+ E) E) }/ m8 A) [
info level number
8 k. T' B, t, _' _/ H' U- H. e如果不给参数number则返回当前的在栈中的绝对位置,参见uplevel中的描述。如加了参! b0 j# x% I' M/ q& S7 F
数number,则返回一个列表包含了在该level上的命令名和参数。
9 ]6 g2 R; n: _info library
6 }3 l5 O# o. y+ f. n8 s返回标准的Tcl脚本的可的路径。实际上是存在变量' I- F) d; G( s) E7 ]; I" Q. J
tcl_library中。" o7 l9 C' D* X( X; a
info locals* J I# h6 P; U( Q
info locals pattern9 T: T! i2 j9 u k$ b4 `: J
返回locale列表。
1 y7 v' X0 w {+ E4 a R9 ^6 Cinfo procs8 u+ ?$ E8 {. B! v$ T) |
info procs pattern' M7 Y, L' }9 X8 P7 p7 N
返回所有的过程的列表。
# f% ~9 x" \- yinfo script& S% j6 c' h" J1 ]
返回最里面的脚本(用 source 来执行)的文件名。* k' M2 o" w' |
info tclversion
: w. z( k- W& _0 p5 p1 `7 \, |返回Tcl的版本号。
4 B2 E1 h. n( l% v* g2 y! v) Zinfo vars
+ W8 p% J; {+ k* e/ V# k" kinfo vars pattern
$ A( U. g) D. v1 V& \/ P8 j返回当前可见的变量名的列表。2 U! P) t7 b* q; {0 V: o( l
下面是一些用于列表的命令,范围可以是end。
/ ?; q U! B% R) X/ R; b1 B% bjoin list- B# a1 k3 [; P) g1 o, I
join list joinString5 N; h3 S4 G( \7 W
将列表的内容连成一个字符串。6 e( T! _. G; M% b
lappend varName value ...! o* N, H9 w9 P4 o* o G6 U% B
将value加入列表varName中。
+ Y5 H8 F5 d6 U$ W) e1 Ulindex list index
$ }$ D3 e ?; j/ I2 ]: g4 o将list视为一个列表,返回其中第index个。列表中的第一个元素下标是0。& c2 n' ]4 _( C% ~, G" f& i
lindex "000 111 222" 1
" p+ ?: W- k |3 z: Y8 A1114 ?: r C1 q# p5 T7 x2 Y% x# O
linsert list index element ...
; |5 Q" J9 n1 X在列表中的index前插入element。
/ t+ e& T" u, c. o, Plist arg ...
% F7 F3 v8 o; O# c将所有的参数发在一起产生一个列表。
" \, R* A, k. E9 \( D, jlist friday [exec ls] [exec cat /etc/passwd]9 P4 Z, Z. a4 P! F* ~
llength list
4 Q6 C) p; ^+ Y4 K: P+ ?0 {返回列表中元素的个数。: ~& z/ q' S& b6 E: i) v
set l [list sdfj sdfjhsdf sdkfj]
( M8 @2 d5 l# ?' x# q" x: `! _, ?llength $l
. [, F6 J* H) {; M- W" h//return 31 s) m' Y9 Y% W8 e
lrange list first last
/ s3 I6 W) ~" Z* Y* r返回列表中从frist到last之间的所有元素。
1 ~2 ?3 ^" y9 B# I* h1 {set l [list 000 111 222 333 444 555]
( {$ p! d% H1 \ m2 e7 E( vlrange $l 3 end
' t, B6 r% R: k+ |% n. O4 L//return 333 444 5551 V/ w0 ^1 h/ l9 O0 a
lreplace list first last8 v8 N5 y* O" V7 \! P, `' m
lreplace list first last element ... z5 N" A% m9 u1 w
替换列表中的从first到last的元素,用element。
; O$ ^; o0 v; X4 `( ?set l [list 000 111 222 333 444 555]
8 `$ D9 b& t' F# Flreplace $l 1 2 dklfj sdfsdf dsfjh jdsf
& g$ Z+ V f+ H* g- G000 dklfj sdfsdf dsfjh jdsf 333 444 555
! |% S) ~$ _* w1 l4 ~' R5 B9 ]lsearch -mode list pattern$ t W o6 N7 y% w
在列表中搜索pattern,成功返回序号,找不到返回-1。3 r8 v; [. E9 s$ w4 x; S8 e( f/ k
-mode : -exact 精确# q/ y" W I; f4 {" B3 l; z; |# O
-glob shell的通配符
9 m' V# W; E) q/ g: l @5 z, N& d-regexp 正则表达式
+ u3 T2 A+ b+ B8 F- L+ {lsearch "111 222 333 444" 111& b; t9 z' f- ]# a/ F( |3 J
//return 0
. j7 U7 o( f, C% Elsearch "111 222 333 444" uwe% @' H# G! h* b3 {# Q) t0 m7 J. F
//return 1
2 q8 C6 Q/ A' Y3 m( Klsort -mode list0 l2 B6 B. j0 s/ w
排列列表。
4 E& p6 z' {% m+ E- p8 [-mode: -ascii0 f/ i; S' P. c& R" b
-dictionary 与acsii类似,只是不区分大小写
; j, ?; A( g! a5 t, c7 w: N-integer 转化为整数再比较
% k8 e* }9 |7 L6 R, T-real 转化为浮点数再比较* |4 {1 U% z4 |9 ]0 d
-command command 执行command来做比较
1 ~5 p! N# z, nopen fileName3 w' [. |/ Z% J U3 j0 Z
open fileName access
! L* ?1 ?! O( R- P# I" H打开文件,返回一个文件描述符。
; P9 N. ^8 W: \7 Eaccess6 e% k, Z& \+ e S2 m" Z
r w a r+ w+ a+
- y% }4 ^7 [0 u定义与C中相同。如文件名的第一个字符为|表示一管道的形式来打开。
- j2 _" J7 N6 u2 E0 h Q( {1 h# Dset f [open |more w]; d: ]8 j$ T, t" |$ C6 Q
set f [open /etc/pass r]# U9 Q: ?( V" G) p$ L. a m
proc name args body
. [9 o& F1 i0 L2 j* G. X% x创建一个新的过程,可以替代任何存在的过程或命令。
- s0 N% R( q: e1 m' ?8 Mproc wf {file str} {+ d5 H8 L5 r6 R" B/ x$ H& @
puts -nonewline $file str9 U, U9 T, D+ B( ~3 D
flush $file" I( E i" G8 c: {
}
9 y; B* ?: H1 Y0 C& c" Nset f [open /tmp/a w]
* @( b. U1 v3 M3 p1 N( u4 cwf $f "first line "9 P. t) S# C G, e, d, P
wf $f "second line "% t7 y" a" }6 [% p, P. y
在函数末尾可用 return 来返回值。* X6 x+ c: e6 p P3 g( g3 n$ |, g
puts -nonewline fileId string
. [) c+ F; n; \0 \) n3 i向fileId中写入string,如果不加上 -nonewline 则自动产生一个换行符。3 M6 M8 u" Q w+ Y
pwd! [; T$ ~% t( \2 f3 \8 T3 g
返回当前目录。
0 r# m0 o/ T8 |" r6 E. g6 }read fileId) _, W$ N) P& T/ c/ }7 A6 u
read fileId numBytes$ a& d) F; |& i, f
从fileId中读取numBytes个字节。
E0 o* j0 j9 j) c# a' Yregexp ?switches? exp string ?matchVar? ?subMatchVar/ l3 m* ?, c- C( r5 V7 [2 K
subMatchVar ...?
- G# S; N( E2 E7 i. ?执行正则表达式的匹配。
4 F1 F' A# H! @?switches? -nocase 不区分大小写
* p* ]# L; d/ Y! l' U; S-indices 返回匹配区间
" ^" u$ Q5 Y" _ A. k7 N如:
$ y, d! {/ Y) d2 O- o# L4 h: W" w# tregexp ^abc abcjsdfh
3 A' m1 |5 u5 o8 d3 T7 L$ n//return 15 B% c, a$ X! Y9 b
regexp ^abc abcjsdfh a/ ~5 [/ l: c' j& J( O) m0 [1 R
//return 13 W' J5 u6 T% [5 \8 K
puts $a
! _# [0 Q; x) g5 H/ O* L4 f- |6 v//return abc$ E% i5 v6 B& m# {
regexp -indices ^abc abcsdfjkhsdf a
7 J2 }. U N, \8 |//return 1
* D1 y6 Z, @- B% I1 `puts $a
4 ?. c$ |5 t( z2 _/ g//return "0 2". E1 h' d7 f) y* Z7 N5 J& T% s. d+ Q* n
regsub ?switchs? exp string subSpec varName* m1 X) T8 R- O6 W% t* I/ M8 A
执行正则表达式的替换,用subSpec的内容替换string中匹配exp的部分。
! r' b" ^ ? e* |?switchs? -all 将所有匹配的部分替换,缺省子替换第一个,返回值为替换的个数。
# X6 P) G( E6 b8 |3 x-nocase 不区分大小写。
1 S Y& h# Q4 e W* R如:
8 v* v/ ~$ Y- P Q" m" vregsub abc abcabcbac eee b) n- P2 \2 [" ~3 d1 T6 j& T9 K, C
//return 1
u) _! u6 U* j) ^/ i7 cputs $b
, r5 O. z d2 Z: N8 @1 k//return "eeeabcabc"
5 H3 v' E; G! V# i- ~" mregsub -all abc abcabcabc eee b: y2 f% H% k" W1 n
//return 3. j6 {6 W8 k* A! ?
puts $b! R5 @2 B0 @. L- N7 w2 B3 \, p- c
//return "eeeeeeeee"% E0 I$ r& m' \" C, n1 B$ j4 C. Z, V
return
. \( [" L- n; \' ]8 @1 K立即从当前命令中返回。
5 m7 y. e" [! o. D: F2 l# vproc ff {} {
* P% L7 [. V1 oreturn friday
. v# u% H' k$ j' Y}
, V7 w% u; a6 {4 P0 ?, Jset a [ff]
% b) r- w2 s2 H5 O//a = "friday"
2 d# B$ ^$ y# r2 v$ M! Iscan string `format" varname ...
3 s% D' V8 N6 D1 E从string中安format来读取值到varname。
) {7 B! f/ u8 L Z- M+ I( H" aseek fileId offset ?origin?
6 E& J; R6 K; ^0 p移动文件指针。 x! F& D s; Q: X) y
origin: start current end6 n* S# h5 ~/ D5 `4 f; Q
offset从哪里开始算起。
; W! o) l* a/ g9 r# ^" oset varname ?value?
/ n1 f7 E: b% i7 F2 q. O设置varname用value,或返回varname的值。如果不是在一个proc命令中则生成一个全局' g( D" K5 U9 A" j. M" C k; Z2 d
变量。
0 q9 j: |' v" ?$ a% Z3 a* Y8 ]source fileName% r. E) Z' U# s- I% E/ ?4 C' o6 ^
从filename中读出内容传给Tcl解释起来执行。) a. i! M- s! y+ C4 ]
split string ?splitChars?( g5 ? j& h, r4 u4 o
将string分裂成列表。缺省以空白为分隔符,也可通过splitChars来设定分隔符; \5 l4 G9 b6 `3 x9 R
string subcommand arg ...' s0 O; n8 {2 }' I. o6 r
用于字符串的命令。
8 i, J7 _5 g; T" l& R5 s8 Astring compare string1 string2. X& R" N5 Q6 `
执行字符串的比较,按 C strcmp 的方式。返回 -1, 0, or 1。
0 z( F& ^1 L8 V! O* \* Qstring first string1 string2
* Q: o: o( d0 {2 m8 R' r1 }) a8 v; p在string1种查找string2的定义次出现的位置。未找到返回-1。# {6 h( P7 D( k( t i5 b+ D' p* u
string length string% `- z# S8 F5 x- O: U# z, t
返回字符串string的长度。
7 G8 E8 ?' c5 pstring match pattern string
/ n+ P" u! G7 o4 o6 x判断string是否能匹配pattern。pattern是以shell文件名的统配格式来给出。* _& o- j0 G @/ s
string range string first last5 I6 X: P* |: X; u
返回字符串string中从first到last之间的内容。
4 m, U. Q, w0 Z- `) F* Kstring tolower string
& _6 Y! W7 P5 S" Z将string转换为小写。
( V4 p; Q* K* Ustring toupper string m! S: I. Q0 ~- a1 Q1 p! C
将string转换为大写。
& @8 o/ n" x9 B; K' x/ M7 N( K8 Kstring trim string
/ @( F( O8 u1 H( S, Z) V将string的左右空白去掉。; ?) y6 ~: w. y- i
string trimleft string* n" S* B6 ~* h. ]/ O
将string的左空白去掉。+ s+ B# H7 m4 ~5 P( a! Y
string trimright string* z7 J0 j4 c1 v; ]5 Y) m
将string的右空白去掉。$ J1 g# a$ V5 A( D: K
tell fileId
2 C- q. p9 G g1 k# M返回fileId的文件指针位置。
: Y: n3 v0 J2 }+ ?) [* ftime command+ m5 O3 b0 [3 r4 D$ E& f
执行命令,并计算所消耗的时间。
' P4 A; D/ a' @time "ls --color"
$ ~8 J( y5 ~$ k% u! l) Hsome file name- N+ m3 f! v5 e* ?, ~# ^
503 microseconds per iteration' ]4 s o( L+ G
trace subcommand
8 C. j8 d- @6 W, u N5 ttrace subcommand arg ...2 J* H; [8 {3 t3 @- ~
监视变量的存储。子命令定义了不少,但目前只实现了virable。
% W7 S$ f, h, D" ctrace variable name ops command4 y. B5 B! L$ _3 Q
name 为变量的名字。
# m0 v+ w# ^- A) ~5 z' f8 [ops 为要监视的操作。
3 ~) k5 |; A B8 `. v+ tr 读
2 N5 c" a6 ~- @" B0 K9 W3 bw 写, o: ?! d$ I+ M' v, ]
u unset1 a$ L2 H8 d3 N( x7 S+ B* h) Y/ o
command 条件满足时执行的命令。
1 k {- ?- z) {6 ^' P: s2 G以三个参数来执行 name1 name2 ops) B2 ~: a; s; c. [
name1时变量的名字。当name1为矢量时,name2为下标,ops为执行的操作。 h6 A1 |- G+ U. P4 e
例如:
- ~# g% U& Y. C4 k$ f/ d N+ \+ \7 yproc ff {name1 name2 op} {, w y7 z6 f7 O3 U: A
puts [format "%s %s %s" name1 name2 op]
- g: {: y, e; [3 Z# N7 L& A! h}& k4 b+ z+ y3 p# c1 }
set a hhh3 q# K2 ?0 b/ Y- G4 b+ _3 t
trace variable a r {ff}# ~+ z# ^$ m v3 @
puts $a
7 K, h0 E% _" J0 `) b9 F//return "a r hhh"9 [; d9 h) r4 M Q ?
unknown cmdName
/ ^9 g4 m: J: Z4 l) J5 ~6 i% Lunknown 并不是 Tcl 的一部分,当 Tcl 发现一条不认识的命令时会看看是否存在 unknown
/ a4 s/ h- Q j# W% `命令,如果有,则调用它,没有则出错。
8 e4 u) J8 G, w: a5 b' ^如:$ o( X: [7 J* O" t5 Q% Y
#!/usr/bin/tclsh
0 e: @. k' ]. d$ o8 K8 }6 ~proc unknown {cwd args} {
/ r, D) s! G* C" Q; Eputs $cwd+ c O. K! I5 e4 E! R8 P
puts $args- a7 X6 q5 ?9 ]7 m+ Q
}
' C% O* a3 _: B//下面是一条错误命令
: Q- }8 s* I7 R' w: i9 W0 A! qsdfdf sdf sdkhf sdjkfhkasdf jksdhfk: o) x. P W( C: X3 j& {& a
//return "sdfdf sdf sdkhf sdjkfhkasdf jksdhfk"
/ Z4 i, J: e9 c" C( munset name ...2 N/ p' k6 e9 u2 |6 R: s
删除一个或多个变量(标量或矢量)。
. V( D* z* M. R# [1 t7 n: Puplevel command ...
' }8 a8 v: a: h2 }" c1 A将起参数连接起来(象是在concat中)。最后在由level所指定的上下文中来执行。如果
; v9 J: `0 r5 H. ?& d& dlevel是一个整数,给出了在栈中的距离(是跳到其它的命令环境中来执行)。缺省为1# c/ ~" w8 U2 A9 f9 p- o) |* L6 g
(即上一层)。
4 E7 `3 Y# h2 z1 i/ ~如:
) P+ I1 k; b7 a3 S+ D1 H#!/usr/bin/tcl* R; ~" P2 L/ N7 X0 i ]; ?
proc ff {} {
0 U; B5 G: E8 k3 v7 ~ hset a "ff" //设置了局部的a% r3 [2 A$ z) B& j& E/ \* m5 ?1 N* @
-------------------------2 z) r* V, D5 m) J: W" {
}# G2 M2 Z5 a9 p8 ?9 s! T
set a "global"
B1 R, U+ E" C }$ e$ V `ff/ k" G( p: j0 c0 e
puts $a
6 F: X0 Y6 a5 x S7 j- y7 Z W//return "global"
% @9 B2 O! e1 {2 i8 K) b再看下一个:
8 n. \, l/ W6 ~5 }; ^, L1 C! z#!/usr/bin/tcl
- O/ M" x/ u* G0 `proc ff {} {4 h6 }1 ~: m- A1 Y$ u3 g* Q
uplevel set a "ff" //改变上一级栈中的a
1 r" d4 A; l) R/ h: n& g-------------------------------------
V9 }3 @2 F0 }% Z5 C}" Q2 u+ v/ ^; p) i2 K
set a global# y/ Q9 A, P p+ j, v( P
ff
9 s2 x9 J% ~2 hputs $a8 C" B7 J" m- `
//return "ff"
7 D7 p- i( W+ x, \2 j, L. J6 Q' g如果level是以#开头后接一个整数,则level指出了在栈中的
: v9 t0 o; |7 {1 c* q: V2 F绝对位置。如#0表示了顶层(top-level)。& I" k) h4 j6 p# F
a b c 分别为三个命令,下面是它们之间的调用关系,
* R; Z' l. f) [6 _( i' btop-level -> a -> b -> c -> uplevel level
* ~* N! h6 N$ f* J! N4 y绝对位置: 0 1 2 3. Q: Z2 T: Z4 W2 U6 c1 u, l
当level为1或#2都是在b的环境中来执行。3或#0都是在 top-level 的环境中来执行。
; s M N1 `- ^upvar ?level? otherVar myVar ?otherVar myVar ...?, r i# t! o1 [4 u4 L
在不同的栈中为变量建立连接。这里的level与uplevel中的level是同样风格的。
; t- o% _- E+ v; c" N- |& ?3 P1 h0 O例如:
7 _8 {8 m$ X$ _. m* x, Q#!/usr/bin/tcl1 A5 U) D2 Q+ k1 F
proc ff {name } {; H# @0 x/ }2 z
upvar $name x
) a* f+ g0 \) l% \set x "ff"
; R% o9 b; N* o7 D9 ^}
* r0 P8 N0 K* q! S9 Q; m3 j& R4 V ?+ Zset a "global"
3 }0 n$ O( @7 Yff a
3 @4 ~" k2 K3 G8 K0 Fputs $a4 Z* z- h) f% X7 Z) J3 x' v
//return "ff"" u1 ]* r' m# I, ]; G4 y* `9 l
while test body
- r% c* {% G9 @举个例子吧:
3 H! ]0 m. b! h1 lset x 0$ G" T' ~; v6 V3 g
while {$x<10} {9 A+ Q9 V! U% l, S7 C
puts "x is $x"" t {; j7 V' P" F, s/ x* W
incr x
; t% d% Z8 L9 C* R& J# G; E}
4 E) }, \, V c) V$ A3 rBuilt-in variables 内建的变量+ P5 j5 ~! o$ p1 P3 T. i
下名的全局变量是由 Tcl library 自动来管理的。一般是只读的。
8 Z( l3 H; [1 X( `env
0 A/ r8 q4 c$ L: `环境变量数组。
3 E) N7 J' o: t; r9 E! J! h5 |: E如:
+ _" z- n& ^; a* Qputs $env(PATH)) \+ r9 f# e N. i
// return /bin:/usr/bin:/usr/X11R6/bin; A. Y; O) p1 X9 K
errorCode
, c! A- K5 g, j% J, T* B当错误发生时保存了一些错误信息。用下列格式来存储:
. v5 M. W- P4 G( eCHILDKILLED pid sigName msg3 g' d4 q, f4 a% M* T1 A- I
当由于一个信号而被终止时的信息。
) t' |! h! X- qCHILDSTATUS pid code
5 V- a' k, {6 }当一个子程序以非0值退出时的格式。$ H5 } O, u% f+ |
CHILDSUSP pid sigName msg" L& \, k% K8 |( P' A
当一个子程序由于一个信号而被终止时的格式。
% d3 J7 G9 `5 O' J* l3 TNONE
4 a! ?& u: H* Q8 _# [4 A+ F错误没有附加信息。
6 T/ w6 Z& n l* s4 iUNIX errName msg: h* J) [ {) y% F- V& U5 f
当一个内核调用发生错误时使用的格式。0 o5 X! B8 n7 v W# L1 q Y
errorInfo
! Z: ^: W# T6 ?1 @/ C) L, Q包含了一行或多行的信息,描述了错误发生处的程序和信息。- r [# `. N M! s5 L3 o
Tcl 名字空间
& W8 J2 }; I7 j6 @8 h/ L3 b/ Lnamespace
0 R% K" J& M4 }4 x# b8 R3 t创建和操纵命令和变量的上下文(content)。, {/ j) m9 a/ k, z- j
简介:
+ k1 @, b) m, g8 E# K w0 l一个名字空间是一个命令和变量的集合,通过名字空间的封装来保证他们不会影响其它名字: h m; M: p8 K+ T( d( ^: L
空间的变量和命令。 Tcl 总是维护了一个全局名字空间 global namespace 包含了所有的
- X/ `! h$ k2 o; l8 E' U! G* D' [全局变量和命令。
0 U# \2 e# T% z/ f6 z/ unamespace eval允许你创建一个新的namespace。! K2 a6 G4 e2 o2 B; T
例如:
0 H9 m* m* Q2 Q* J# U4 mnamespace eval Counter {: Y: v- l0 V( e2 l5 N' m1 p; y# W
namespace export Bump" n- I6 i+ }. f. A
variable num 0
* ]/ f! J/ r; i j4 b2 Q% Vproc Bump {} {
/ \& r c5 [) W' a! s' ]/ ]variable num//声明局部变量
, S, q$ w1 h2 D. p0 ]incr num
* Q( n# R3 y- v+ N6 i, J}
# i* u* B5 C8 A" T% D. R}/ I. t- R t# w( M% B: _# I* K
名字空间是动态的,可变的。
: w) O* o5 Z5 K8 {2 J" P8 j例如:0 N v5 [1 @, y7 C4 c, B T
namespace eval Counter {+ j$ z7 g) n1 I1 S: {
variable num 0//初始化1 e$ o/ o! K( ~
proc Bump {} {
) @: v- T9 h6 J* x7 k! a( p& y/ w! Jvariable num# K8 C9 \, C- ~$ B& M1 w; E
return [incr num]
3 {2 T: D& ^* n3 |: o: U: `+ a}
, ^1 u2 O# B, [0 Y; `# u; \1 ], P}7 }$ M5 _) p7 k8 i1 x% ]
//添加了一个过程/ l* `" L5 A h3 W4 q6 h/ B* x# U3 s
namespace eval Counter {9 a7 @) L* n' C) N" U' D/ q: w" O
proc test {args} {/ h* d6 j9 a; \- ?' |2 ?" P4 y
return $args, O$ T6 f4 X$ I* k. s
}
6 W( V5 ^+ s* k}6 G# x" t" v: \0 {( Y+ \* x
//删除test
" _% a [0 K! Ynamespace eval Counter {: B$ |- \" L+ Z9 f, p2 r0 E9 V$ _
rename test ""
- C2 f/ `& X. s h}
! N0 n* ]5 t& V引用:9 Z! z8 ~% @, L3 J
set Counter::num
- I+ U. v1 q7 ]( _//return 0
6 Q: z; o+ m9 ~0 r* I也可以用下面的方式添加:
; n9 V. I: j+ c; n+ B7 `proc Foo::Test {args} {return $args}
7 K4 g E( O, C5 o& ?或在名字空间中移动:$ E3 C1 d/ v5 @6 ?+ e
rename Foo::Test Bar::Test |
|