赞
踩
1. source的用途
Ø 将一个程序分为多个文件;
Ø 可以将一组过程放到一个文件中,成为一个库文件;
Ø 配置程序;
Ø 加载数据文件。
2. 格式:source fileName
说明:
Ø 读入文件并执行;
Ø 如果代码出错,source返回那个错误
Ø 如果执行到返回,就立刻返回,即便返回命令后面还有命令也不执行立刻返回
Ø 如果文件名以 ~ 开头,替换为环境变量 $HOME
例子:031_source.tcl
set filename "C:\\windows\\temp\\TT_[pid]"
set outfile [open "$filename" "w"];
puts $outfile {set scr [info script]}
puts $outfile "proc testproc {} {"
puts $outfile "global scr;"
puts $outfile "puts \"testproc source file: \$scr.\""
puts $outfile "puts \"testproc executing from \[info script]\n\""
puts $outfile "}"
puts $outfile {set abc 1};
puts $outfile {return};
puts $outfile {set aaaa 1} ;#没有执行这一句
close $outfile;
puts "This is the contents of $filename:"
puts ".............................................................."
puts "[exec cmd /C type $filename]"
puts ".............................................................."
puts "\n"
puts "Global variables visible before sourceing $filename:"
puts "[lsort [info globals]]\n"
if {[info procs testproc] == ""} {
puts "testproc does not exist. sourceing $filename"
source $filename ;#加载上过程后,就可以调用了
}
puts "\nNow executing testproc"
testproc ;#执行过程
puts "Global variables visible after sourceing $filename:"
puts "[lsort [info globals]]\n"
exec cmd /c del $filename ;#删除该文件
1. 自动加载库文件的方法:
2. 建库的相关函数列表
序号 | 函数 | 描述 |
1 | auto_mkindex libdir file1...filen | 为库文件创建索引文件(tclIndex),自动加载库的过程定义在init.tcl 文件中,当tclsh启动的时候执行 |
2 | info library | 返回库所在路径,实际是环境变量TCL_LIBRARY的值,tcl会在该路径下查找init.tcl |
3 | unknown args | 当解释器遇到调用索引文件中不存在的过程是,该函数尝试下面的步骤来执行命令: 1. 查找auto_path的路径中的索引文件,如果找到过程定义,使用auto_load过程加载执行; 2. 如果解释器交互执行的,tcl尝试使用过程auto_exec去执行; 3. 如果命令是个不带后缀名的tcl命令,unknown完善命令名字,并执行 |
例子:032_source.tcl
;# Set up a temporary file with a test proc.
set filename "C:/temp/TT_[pid]" ;#1. 生成文件
set outfile [open "$filename" "w"];
puts $outfile {set scr [info script]}
puts $outfile "proc testproc {} {"
puts $outfile "global scr;"
puts $outfile "puts \"testproc source file: \$scr.\""
puts $outfile "puts \"testproc executing from \[info script]\n\"" ;#注意:返回的是032_source.tcl 而不是TT_[pid]
puts $outfile "}"
close $outfile;
puts "The directories in the auto path are: $auto_path\n"
puts "The default library is: [info library]\n";
auto_mkindex "C:/temp" [file tail $filename] ;#2. 对文件建立索引文件,c:/temp 路径下生成索引文件 tclIndex
# With Tcl8.3, this must come after auto_mkindex.
lappend auto_path "C:/temp" ;#3. 将库的路径加到 auto_path 中
if { [info procs testproc] == ""} {
puts "testproc does not exist\n"
}
testproc
if { [info procs testproc] != ""} {
puts "\ntestproc does exist now"
}
file delete C:/temp/tclIndex
file delete $filename
1.在程序运行的过程中,tcl可以执行其中创建的命令
格式:eval arg1 ??arg2??... ??argn??
功能:将参数连接成一个字符串,传递给tcl_Eval 进行执行,并返回结果或错误码
例子:033_eval.tcl
set cmd {puts "Evaluating a puts"}
puts "CMD IS: $cmd"
eval $cmd
if {[string match [info procs tempFileName] ""] } {
puts "\nDefining tempFileName for this invocation"
set num 0;
set cmd "proc tempFileName "
set cmd [concat $cmd "{} {\n"]
set cmd [concat $cmd "global num;\n"]
set cmd [concat $cmd "incr num;\n"]
set cmd [concat $cmd " return \"/tmp/TMP.[pid].\$num\";\n"]
set cmd [concat $cmd "}"]
eval $cmd
}
puts "\nThe body of tempFileName is: \n[info body tempFileName]\n"
puts "tmpFileName returns: [tempFileName]" ;# 这里$num返回1
puts "tmpFileName returns: [tempFileName]" ;# $num加一,返回2
1.常见的eval错误
ok:eval puts ok
err:eval puts not ok
ok:set x “OK” ; eval puts $x
err:set x “NOT OK”; eval puts $x
not ok被解析为了两个参数
下面三种写法是正确的:
eval [list puts {NOT OK}]
eval [list puts “NOT OK”]
set cmd “puts”; lappend cmd {NOT OK};eval $cmd
结论:对于构建eval的需要的命令,要么使用string的format,要么使用list和lappend。
2.格式:info complete string
功能:检查字符串中的空格,引号,括号等是否匹配,匹配返回一,不匹配返回零
例子:034_format_list.tcl
set cmd "OK"
eval puts $cmd ;#正确
set cmd "puts" ; lappend cmd {Also OK}; eval $cmd ;#正确
set cmd "NOT OK"
#eval puts $cmd ;#出错
eval [format {%s "%s"} puts "Even This Works"] ;#正确
set cmd "And even this can be made to work"
eval [format {%s "%s"} puts $cmd ] ;#正确
set tmpFileNum 0;
set cmd {proc tempFileName }
lappend cmd ""
lappend cmd "global num; incr num; return \"/tmp/TMP.[pid].\$tmpFileNum\"" ;#这里$tmpFileNum不会返回0,会返回$tmpFileNum,因为它是在过程外赋值的
eval $cmd
puts "\nThis is the body of the proc definition:"
puts "[info body tempFileName]\n"
set cmd {puts "This is Cool!"}
if {[info complete $cmd]} {
eval $cmd
} else {
puts "INCOMPLETE COMMAND: $cmd"
}
1.不使用eval的时候,字符串会进行一次置换
例如: set a “sampleA”
set c a
puts “$$c” ;#会返回$a,而不是$a的值
要想进行多次置换,需要使用format或者subst,使用一次置换一次
注意:使用双引号会置换一次,但是使用花括号不会置换
2.格式:subst ?-nobackslashes??-nocommands??-novariables? string
-no后面接什么就不置换什么
例子:
set a "alpha"
set b a
puts {a and b with no substitution: $a $$b}
puts "a and b with one pass of substitution: $a $$b"
puts "a and b with subst in braces: [subst {$a $$b}]"
puts "a and b with subst in quotes: [subst "$a $$b"]\n"
puts "format with no subst [format {$%s} $b]"
puts "format with subst: [subst [format {$%s} $b]]"
eval "puts \"eval after format: [format {$%s} $b]\""
set num 0;
set cmd "proc tempFileName {} "
set cmd [format "%s {global num; incr num;" $cmd]
set cmd [format {%s return "/tmp/TMP.%s.$num"} $cmd [pid] ]
set cmd [format "%s }" $cmd ]
eval $cmd
puts "[info body tempFileName]"
set a arrayname
set b index
set c newvalue
eval [format "set %s(%s) %s" $a $b $c]
puts "Index: $b of $a was set to: $arrayname(index)"
set x "xyz"
set y x
set z y
puts "xyz is : $x
puts "xyz is : [subst "$x
puts "xyz is : [subst [subst "$x
1. 改变工作目录
格式:cd ?dirName?
功能:改变当前目录到dirName,如果没有dirName就改变到当前用户的工作目录$HOME,或者目录是 ~ ,也是改变到当前用户的工作目录$HOME,如果是 ~ 开头,后面紧跟的字符被解析为loginid。
2. 显示当前路径:pwd
例子:036_cd_pwd.tcl
set dirs [list C:/windows C:/windows/system C:/temp C:/foo ]
puts "[format "%-15s %-20s " "FILE" "DIRECTORY"]"
foreach dir $dirs {
catch {cd $dir}
set c_files [glob -nocomplain c*]
foreach name $c_files {
puts "[format "%-15s %-20s " $name [pwd]]"
}
}
1.错误相关:
序号 | 命令或变量 | 描述 |
1 | error message ?info? ?code? | 生成一个错误条件,如果info或者code有值,变量errorInfo或errorCode就这两个值被初始化 |
2 | catch script ?varName? | 执行script,如果成功返回TCL_OK,否则返回TCL_ERROR,结果存在varName中。书上这么说的,但是我的试验结果是失败varName存储的错误信息,成功varName存储的0 |
3 | return ?-code code? ?-errorinfo info??-errorcode errorcode??value? | 生成一个返回异常条件 -code :返回状态,可以是: ok,error,无,break -errorinfo:info是errorInfo变量中的第一个字符串 -errorcode:过程设置errorcode为全局变量的errorCode值 value:过程返回值 |
4 | errorInfo | 包含了命令错误信息的全局变量 |
5 | errorCode | 包含了命令错误代码的全局变量 |
例子:037_error.tcl
proc errorproc {x} {
if {$x > 0} {
error "Error generated by error" "Info String for error" $x
}
}
catch errorproc
puts "after bad proc call: ErrorCode: $errorCode" ;#这里errorCode返回NONE
puts "ERRORINFO:\n$errorInfo\n"
set errorInfo "";
catch {errorproc 0}
puts "after proc call with no error: ErrorCode: $errorCode" ;#这里errorCode返回NONE,没有错误提示信息
puts "ERRORINFO:\n$errorInfo\n"
catch {errorproc 2}
puts "after error generated in proc: ErrorCode: $errorCode" ;#这里errorCode返回2
puts "ERRORINFO:\n$errorInfo\n"
proc returnErr { x } {
return -code error -errorinfo "Return Generates This" -errorcode "-999"
}
catch {returnErr 2}
puts "after proc that uses return to generate an error: ErrorCode: $errorCode" ;#这里errorCode返回999
1.调试方法:
序号 | 命令 | 描述 |
1 | trace variable variableName operation procname | 跟踪变量variableName operation 可以是: r:read ,读 w:write ,写 u:unset ,取消 当变量有相应操作执行procname |
2 | trace vdelete variableName operation procname | 取消变量variableName相应操作operation的跟踪 |
3 | trace vinfo variableName | 返回跟踪的变量variableName的信息 |
例子:
proc traceproc {variableName arrayElement operation} {
set op(w) "Write"; set op(u) "Unset"; set op(r) "Read" ;#定义一个操作数组
set level [info level]
incr level -1;
if {$level > 0} {
set procid [info level $level]
} else {set procid "main"} ;#当级别为零,设置为main,在主程序中
if {![string match $arrayElement ""]} { ;#判断跟踪的变量是否是数组
puts "TRACE: $op($operation) $variableName($arrayElement) in $procid"
} else {
puts "TRACE: $op($operation) $variableName in $procid"
}
}
proc testProc {input1 input2} {
upvar $input1 i
upvar $input2 j
set i 2
set k $j;
}
1.程序和用户交互的方法有很多,以下是其中四种:
Ø 提示用户输入需要信息;
Ø 读入配置文件;
Ø 从命令行读入参数;
Ø 从环境变量读入
2.命令行参数:argc得到参数个数,argv0得到程序自身名字,argv得到其他参数,注意没有argv1这类的全局变量
3.env是存储着环境变量的数组,对环境变量修改只是当前程序中生效了
例子:039_arg.tcl
puts "There are $argc arguments to this script"
puts "The name of this script is $argv0" ;#得到程序名
if {$argc > 0} {puts "The other arguments are: $argv" } ;#得到其他的参数
puts "You have these environment variables set:"
foreach index [array names env] {
puts "$index: $env($index)"
}
set prompt "\$P"
if { [info exists env(PROMPT)] } {
puts "$env(PROMPT)" ;#返回 $P$G
set env(PROMPT) $prompt ;#设置环境变量为$P,程序执行完后仍然是$P$G,因为它只是在该程序中生效了
puts "$env(PROMPT)"
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。