文章出处:51testing 作者:叶晖 兰海 发布时间:2006-03-17
摘 要:unix下使用TCL脚本读取配置文件;错误处理.
关键词:TCL、配置文件、unix
一.应用范围
在实际工作中,TCL脚本对于一些简单的工作裨益甚大。通常编写脚本都有一定的模式,首先从配置文件读入配置项,初始化变量,然后进行处理,最后输出,在程序的运行过程中需要把一些信息写入日志文件,而调试信息写入日志文件和直接输出到屏幕都可以。
使用任何一种脚本,通常也都会根据实际情况建立起自己的函数库,而这个函数库中对配置文件配置项的读取无疑是非常基本而重要的。
这篇文章的本意是引导刚接触TCL脚本的朋友尽快上手,所以有些细节的说明文字比较细。
二.程序讲解
构建一个配置文件,尽可能的接近实际应用:
文件名:config.ini
文件内容:
#
# 这是注释行
#
[]
key1=value1 # 注释
[section1]
key2=value2
[section2]
key1=value2
[section1]
key1=xxxxxx # 这是最后的返回
[section1]
key1=value2
现在开始对程序的说明:
;#-------------------------------------------------------------------------
;# 功能:从配置文件中读取配置项
;# 输入:1. configFile :配置文件名称
;# 2. Section : 段名称
;# 3. Key : 关键字
;# 4. Comment : 注释符,缺省为井号
;# 5. Equal : 关键字和值的分隔符,缺省为等号
;# 输出:1. Value : 相应的值
;#-------------------------------------------------------------------------
1. 过程的定义:
格式:proc name args body
要点:
Ø 参数列表使用花括号引起;
Ø 变量没有类型;
Ø 变量之间使用空格间隔;
Ø 如果参数有缺省值,使用花括号引起,并赋值
proc getConfig { configFile Section Key {Comment "#"} {Equal "="}} {
set Value "" ;# 记录过程返回的值
set FindSection 0 ;# 记录是否找到了section
2.错误的处理
格式:catch script ?varName?
功能:执行script,如果成功返回TCL_OK(0),否则返回TCL_ERROR(1),提示结果存在varName中。比如下面如果打开文件成功,errMsg返回的就是类似file3这样的字符串,此时err返回的是TCL_OK,就是零;如果文件不存在,errMsg返回的类似:couldn't open "config1.ini": no such file or directory,此时err返回TCL_ERROR,就是一。
3.文件的读写
格式:openfile fileName ? access ? permission
讲解:
Ø fileName是文件名称;
Ø access是存取模式,可以为r, r+, w, w+, a, a+ 六种模式,r 、r+ 和a 三种模式文件必须已经存在,其他三种模式文件不存在就创建一个。本文用的 r 模式,所以文件不存在会提示错误,而不是自动建立一个;
Ø permission是权限,举例说明:
有权限为:000 000 000 :第一组三位为user权限;第二组三位为同组其他用户的权限;第三组三位为其他组所有人的权限。每个三位的权限依次代表读,写,执行。如果有相应的权限就设置为一,没有设置为0。然后三位为组转成十进制数。
Ø 文件打开后就可以使用其文件id,使用完后记得关闭文件
;# 打开配置文件
set err [catch {set fileid [open $configFile r]} errMsg]
if {$err == 1} {
puts "errMsg : $errMsg"
return $Value
}
;# 成功打开文件后, 一行一行的加以分析
set rowid 0 ;#记录当前行数,程序调试时打印调试信息使用的
seek $fileid 0 start ;# 定位到文件头
while {[eof $fileid] != 1} { ;# 读取文件内容
4.变量的自动增长使用命令 incr,也可以使用 set rowid [expr $rowid + 1],显然前者更简捷
incr rowid ;# 记录行数, 从一开始
;# 读出一行
gets $fileid line
5.先期处理行,因为注释有两种情况,行中的注释和整行注释,先去掉注释,然后去左右空格就可以得到真正需要的内容;如果先去空格,再去注释,由于行中的注释和内容之间有空格,这样最后得到的内容在去掉行中注释后,会在后面留下一些空格。所以需要先去掉注释,后去掉空格。
6.得到一个字符串在另一个字符串中首先出现的位置,使用函数string first
格式:string first string1 string2
讲解:返回string1在string2中第一次出现的位置;如果string1不在string2中,返回-1
7.下面有一个细节是初学者经常犯错的地方,那就是:} else { ,这里必须严格的 花括号,空格,else,空格,花括号,不能把花括号写到上一行或者下一行。
8.返回一个字符串的子串使用string range函数
格式:string range string1 frompos topos
讲解:取string1的从frompos到topos之间的字符串,注意这里字符串下标是从零开始的,所以用string length string1得到的字符串的长度比字符串最后一个字符的位置值要大一。如果取一个字符串中的某个字符就可以使用函数string index string1 pos。
9.expr 和unix shell中一样,是进行数学运算的函数。
;# 先去掉注释, 再去掉两端的空格
set commentpos [string first $Comment $line] ;# 得到注释符号的位置
if { $commentpos == 0 } {
;# 行以注释符号开头,忽略掉该行
} else {
if { $commentpos != -1 } { ;# 行中有注释符号,去掉注释
set line [string range $line 0 [expr $commentpos-1]]
}
set line [string trim $line] ;# 去掉两端的空格
;# puts "$rowid : line : $line"
10.在tcl脚本中,循环中有break命令跳出循环,continue跳到循环的开头。不过因为括号的使用,其实这里写不写continue都没有问题。
;# 如果是空就继续循环
if { $line == "" } {
;# 回循环
continue
} else {
;# 先找section
set linelen [string length $line] ;#字符串长度
set lastpos [expr $linelen - 1 ] ;#字符串最后的位置
;# puts "$rowid :len: $linelen lastpos: $lastpos"
if { [string index $line 0] == "\[" && [string index $line $lastpos] == "\]" } {
;# 如果是查找的section, 修改标志位;如果不是相应的section, 需要将标志重新赋值
if { [string range $line 1 [expr $lastpos - 1 ]] == $Section } {
;# puts "$rowid: find section : $Section"
set FindSection 1
} else {
set FindSection 0
}
} else {
;# 已经找到了section才继续找key
if { $FindSection == 1 } {
set equalpos [string first $Equal $line] ;# 得到等号的位置
if { $equalpos != -1} {
;# 如果就是找寻的key,结束循环
if { [string range $line 0 [expr $equalpos - 1]] == $Key } {
puts "$rowid: find key"
set Value [string range $line [expr $equalpos + 1] [string length $line]]
puts "$rowid: find value: $Value"
break
}
} else {
;# 回循环
}
} else {
;# 回循环
}
}
}
}
}
;# 关闭文件
close $fileid
return $Value
}
set val ""
;# 测试正常情况下
set val [getConfig "config.ini" "section1" "key1"]
puts "val : $val"
;# 测试文件不存在的情况下
set val [getConfig "config1.ini" "section1" "key1"]
puts "val : $val"
该程序在unix 环境下调试通过。
三.伪代码
为了便于理解程序,特写了下面的伪代码:
打开配置文件
IF 出错 THEN
过程结束
END IF
文件打开成功,定位到文件头
WHILE 没有到文件尾
读出一行
处理得到的行,先去掉行中的注释,再去掉行左右的空格
IF 行为空 THEN
ELSE
行不为空
IF [开头 ]结束 THEN
得到SECTION
IF 得到的SECTION就是要找的SECTION THEN
置标志位
ELSE
清空标志位
END IF
ELSE
IF 已经找到SECTION了 THEN
IF 行中有等号 THEN
IF 等号左边的是在查找的KEY THEN
取得等号右边的值,跳出循环
ELSE
等号左边不是在查找的KEY,继续下一行
END IF
ELSE
行中没有等号,继续下一行
END IF
ELSE
还没有找到SECTION,继续下一行
END IF
END IF
END IF
关闭文件
返回值
四.讨论
这个程序本身比较简单,主要目的是想通过这个程序让tcl初学者对tcl有个感性认识。真正在工作使用中,这个脚本需要改进的地方还有很多。
比如配置文件比较小的话,可以读一个配置项打开一次文件。当配置文件大了以后,这种方法显然效率比较低,可能需要一次将文件的内容全部读入一个列表中,然后进行读取,这样速度会有提高。再比如错误处理只是在过程中将错误信息显示到屏幕上,是不是应该定义一个错误信息的全局变量来传出过程,或者使用upvar 直接修改错误信息变量。否则返回的值是空,并不能确定是配置的值的确是空还是执行中出现了错误。
抛砖引玉,共勉。如有错误,望不吝赐教。
摘 要:unix下使用TCL脚本读取配置文件;错误处理.
关键词:TCL、配置文件、unix
一.应用范围
在实际工作中,TCL脚本对于一些简单的工作裨益甚大。通常编写脚本都有一定的模式,首先从配置文件读入配置项,初始化变量,然后进行处理,最后输出,在程序的运行过程中需要把一些信息写入日志文件,而调试信息写入日志文件和直接输出到屏幕都可以。
使用任何一种脚本,通常也都会根据实际情况建立起自己的函数库,而这个函数库中对配置文件配置项的读取无疑是非常基本而重要的。
这篇文章的本意是引导刚接触TCL脚本的朋友尽快上手,所以有些细节的说明文字比较细。
二.程序讲解
构建一个配置文件,尽可能的接近实际应用:
文件名:config.ini
文件内容:
#
# 这是注释行
#
[]
key1=value1 # 注释
[section1]
key2=value2
[section2]
key1=value2
[section1]
key1=xxxxxx # 这是最后的返回
[section1]
key1=value2
现在开始对程序的说明:
;#-------------------------------------------------------------------------
;# 功能:从配置文件中读取配置项
;# 输入:1. configFile :配置文件名称
;# 2. Section : 段名称
;# 3. Key : 关键字
;# 4. Comment : 注释符,缺省为井号
;# 5. Equal : 关键字和值的分隔符,缺省为等号
;# 输出:1. Value : 相应的值
;#-------------------------------------------------------------------------
1. 过程的定义:
格式:proc name args body
要点:
Ø 参数列表使用花括号引起;
Ø 变量没有类型;
Ø 变量之间使用空格间隔;
Ø 如果参数有缺省值,使用花括号引起,并赋值
proc getConfig { configFile Section Key {Comment "#"} {Equal "="}} {
set Value "" ;# 记录过程返回的值
set FindSection 0 ;# 记录是否找到了section
2.错误的处理
格式:catch script ?varName?
功能:执行script,如果成功返回TCL_OK(0),否则返回TCL_ERROR(1),提示结果存在varName中。比如下面如果打开文件成功,errMsg返回的就是类似file3这样的字符串,此时err返回的是TCL_OK,就是零;如果文件不存在,errMsg返回的类似:couldn't open "config1.ini": no such file or directory,此时err返回TCL_ERROR,就是一。
3.文件的读写
格式:openfile fileName ? access ? permission
讲解:
Ø fileName是文件名称;
Ø access是存取模式,可以为r, r+, w, w+, a, a+ 六种模式,r 、r+ 和a 三种模式文件必须已经存在,其他三种模式文件不存在就创建一个。本文用的 r 模式,所以文件不存在会提示错误,而不是自动建立一个;
Ø permission是权限,举例说明:
有权限为:000 000 000 :第一组三位为user权限;第二组三位为同组其他用户的权限;第三组三位为其他组所有人的权限。每个三位的权限依次代表读,写,执行。如果有相应的权限就设置为一,没有设置为0。然后三位为组转成十进制数。
Ø 文件打开后就可以使用其文件id,使用完后记得关闭文件
;# 打开配置文件
set err [catch {set fileid [open $configFile r]} errMsg]
if {$err == 1} {
puts "errMsg : $errMsg"
return $Value
}
;# 成功打开文件后, 一行一行的加以分析
set rowid 0 ;#记录当前行数,程序调试时打印调试信息使用的
seek $fileid 0 start ;# 定位到文件头
while {[eof $fileid] != 1} { ;# 读取文件内容
4.变量的自动增长使用命令 incr,也可以使用 set rowid [expr $rowid + 1],显然前者更简捷
incr rowid ;# 记录行数, 从一开始
;# 读出一行
gets $fileid line
5.先期处理行,因为注释有两种情况,行中的注释和整行注释,先去掉注释,然后去左右空格就可以得到真正需要的内容;如果先去空格,再去注释,由于行中的注释和内容之间有空格,这样最后得到的内容在去掉行中注释后,会在后面留下一些空格。所以需要先去掉注释,后去掉空格。
6.得到一个字符串在另一个字符串中首先出现的位置,使用函数string first
格式:string first string1 string2
讲解:返回string1在string2中第一次出现的位置;如果string1不在string2中,返回-1
7.下面有一个细节是初学者经常犯错的地方,那就是:} else { ,这里必须严格的 花括号,空格,else,空格,花括号,不能把花括号写到上一行或者下一行。
8.返回一个字符串的子串使用string range函数
格式:string range string1 frompos topos
讲解:取string1的从frompos到topos之间的字符串,注意这里字符串下标是从零开始的,所以用string length string1得到的字符串的长度比字符串最后一个字符的位置值要大一。如果取一个字符串中的某个字符就可以使用函数string index string1 pos。
9.expr 和unix shell中一样,是进行数学运算的函数。
;# 先去掉注释, 再去掉两端的空格
set commentpos [string first $Comment $line] ;# 得到注释符号的位置
if { $commentpos == 0 } {
;# 行以注释符号开头,忽略掉该行
} else {
if { $commentpos != -1 } { ;# 行中有注释符号,去掉注释
set line [string range $line 0 [expr $commentpos-1]]
}
set line [string trim $line] ;# 去掉两端的空格
;# puts "$rowid : line : $line"
10.在tcl脚本中,循环中有break命令跳出循环,continue跳到循环的开头。不过因为括号的使用,其实这里写不写continue都没有问题。
;# 如果是空就继续循环
if { $line == "" } {
;# 回循环
continue
} else {
;# 先找section
set linelen [string length $line] ;#字符串长度
set lastpos [expr $linelen - 1 ] ;#字符串最后的位置
;# puts "$rowid :len: $linelen lastpos: $lastpos"
if { [string index $line 0] == "\[" && [string index $line $lastpos] == "\]" } {
;# 如果是查找的section, 修改标志位;如果不是相应的section, 需要将标志重新赋值
if { [string range $line 1 [expr $lastpos - 1 ]] == $Section } {
;# puts "$rowid: find section : $Section"
set FindSection 1
} else {
set FindSection 0
}
} else {
;# 已经找到了section才继续找key
if { $FindSection == 1 } {
set equalpos [string first $Equal $line] ;# 得到等号的位置
if { $equalpos != -1} {
;# 如果就是找寻的key,结束循环
if { [string range $line 0 [expr $equalpos - 1]] == $Key } {
puts "$rowid: find key"
set Value [string range $line [expr $equalpos + 1] [string length $line]]
puts "$rowid: find value: $Value"
break
}
} else {
;# 回循环
}
} else {
;# 回循环
}
}
}
}
}
;# 关闭文件
close $fileid
return $Value
}
set val ""
;# 测试正常情况下
set val [getConfig "config.ini" "section1" "key1"]
puts "val : $val"
;# 测试文件不存在的情况下
set val [getConfig "config1.ini" "section1" "key1"]
puts "val : $val"
该程序在unix 环境下调试通过。
三.伪代码
为了便于理解程序,特写了下面的伪代码:
打开配置文件
IF 出错 THEN
过程结束
END IF
文件打开成功,定位到文件头
WHILE 没有到文件尾
读出一行
处理得到的行,先去掉行中的注释,再去掉行左右的空格
IF 行为空 THEN
ELSE
行不为空
IF [开头 ]结束 THEN
得到SECTION
IF 得到的SECTION就是要找的SECTION THEN
置标志位
ELSE
清空标志位
END IF
ELSE
IF 已经找到SECTION了 THEN
IF 行中有等号 THEN
IF 等号左边的是在查找的KEY THEN
取得等号右边的值,跳出循环
ELSE
等号左边不是在查找的KEY,继续下一行
END IF
ELSE
行中没有等号,继续下一行
END IF
ELSE
还没有找到SECTION,继续下一行
END IF
END IF
END IF
关闭文件
返回值
四.讨论
这个程序本身比较简单,主要目的是想通过这个程序让tcl初学者对tcl有个感性认识。真正在工作使用中,这个脚本需要改进的地方还有很多。
比如配置文件比较小的话,可以读一个配置项打开一次文件。当配置文件大了以后,这种方法显然效率比较低,可能需要一次将文件的内容全部读入一个列表中,然后进行读取,这样速度会有提高。再比如错误处理只是在过程中将错误信息显示到屏幕上,是不是应该定义一个错误信息的全局变量来传出过程,或者使用upvar 直接修改错误信息变量。否则返回的值是空,并不能确定是配置的值的确是空还是执行中出现了错误。
抛砖引玉,共勉。如有错误,望不吝赐教。
相关推荐
在使用TCL脚本存取二进制文件时,经常遇到的场景包括但不限于硬件配置、数据备份、系统升级等。项目中应用TCL脚本存取二进制文件,通常涉及到对文件的读写、数据的转换、以及格式化等操作,这些都是TCL脚本的强项。 ...
`read_xdc`命令直接读取XDC文件,而`source`命令则更通用,不仅可以加载XDC文件,还可以执行任何TCL脚本或包含其他TCL命令的文件。 **Vivado中的TCL脚本功能** 1. **启动时执行TCL脚本**:用户可以设定自定义的TCL...
掌握如何使用TCL脚本读取配置文件,对于自动化测试任务的高效执行具有重要意义,尤其是当测试环境需要频繁配置变化时。 ### 7. 软件的全球化测试 随着软件产品全球化的趋势,全球化测试变得越来越重要。它涉及确保...
2. **MIB对象操作**:TCL脚本可以读取和修改MIB中的对象值,这对于测试设备的配置和状态管理非常有用。 3. **异常处理**:在测试中,可能需要模拟网络故障或异常情况。TCL脚本能够创建这种条件,帮助验证网络管理...
7. **文件操作**:TCL提供了一系列文件I/O命令,如`open`打开文件,`gets`读取行,`puts`写入内容,`close`关闭文件。 8. **正则表达式**:TCL内置了正则表达式的支持,可以使用`regexp`命令进行模式匹配和替换。 ...
- **SOURCE命令:** 用于读取并执行一个TCL脚本文件中的所有命令。 - 示例:`source myscript.tcl` 5. **可执行脚本文件:** 通过设置文件权限,使得脚本文件可以直接运行而无需使用TCL解释器调用。 6. **获得...
下面将根据提供的压缩包文件内容,详细讲解TCL脚本的学习知识点。 一、TCL基础语法 1. 变量:在TCL中,变量声明是不需要关键字的,直接赋值即可创建。如`set name "John"`用于设置一个字符串类型的变量。 2. 命令与...
在实际工作中,TCL脚本常被用来读取配置文件、初始化变量、执行特定操作并输出结果。此外,为了方便跟踪和调试,还需要将运行过程中的关键信息写入日志文件或直接输出到屏幕上。 TCL脚本的编写通常遵循一定的模式:...
4. **过程自动化**:编写TCL脚本来执行一系列控制台命令,如安装、配置、启动服务等,减少手动操作。 5. **错误检查**:通过`file exists`、`file readable`等命令检查文件状态,确保测试环境的正确性。 6. **正则...
NSG2(Network Simulator Graphical Interface 2)是一款基于Java的图形用户界面工具,用于辅助用户创建网络仿真场景并自动生成.tcl脚本文件,这些脚本文件可以被Ns2(Network Simulator 2)读取和执行,以模拟各种...
1.软件测试常识 2.软件测试过程管理实践 3.论测试人员为什么需要参加需求评审 4.深入理解LoadRunner测试结果. 5.深入浅出单元测试. 6.TU使用TCL脚本读取配置文件. 7.用WinRunner实现软件的全球化测试
1. **路由器和交换机配置测试**:通过TCL脚本,可以方便地读取和解析这些设备的输出信息,从而进行各种功能验证。 2. **协议一致性测试**:利用TCL脚本编写测试用例,确保设备遵循相关通信协议的标准。 3. **性能...
TCL(Tool Command Language)是一种动态编程语言,具有简单、灵活的特点,适合于脚本编写和快速原型开发。在TCL中处理JSON数据,可以极大地提升开发效率,特别是当需要与Web服务交互或者进行数据存储时。 TCL提供...
### 使用Tcl操作Excel文件的方法 #### 一、前言 在日常开发工作中,我们经常需要处理Excel文件,尤其是在进行数据分析或报表制作时。Tcl(Tool Command Language)是一种脚本语言,它提供了强大的文本处理功能及...
根据提供的信息,我们可以了解到这是一份关于NIOS系统配置中的TCL文件的示例。这里主要涉及到了硬件资源分配的问题,即...掌握TCL脚本的编写方法不仅能够提高工作效率,还能使开发者更加灵活地应对各种硬件配置需求。
**TCL脚本语言编程** TCL(Tool Command Language)是一种简单、易学且功能强大的脚本语言,最初由John Ousterhout在1988年开发,主要用于编写自动化测试脚本。随着时间的推移,TCL逐渐发展成为一个通用的编程语言...
shc的工作原理是读取Shell脚本,对其进行编译,并生成一个加密的二进制文件。这个二进制文件在运行时会解密并执行原始脚本的代码,而不会暴露源代码。这种方式为脚本的安全性提供了一层额外的保护。 使用shc加密...
结合描述中的"设备telnet 控制软件",我们可以推测这个压缩包文件包含了一个或多个TCL脚本或程序,它们设计用于通过telnet协议与设备交互,实现远程控制功能。 TTerm,作为压缩包子文件的唯一文件名,很可能是一款...