Tcl中涉及运行程序,查看文件系统和以及通过env数组来存取换将变量的命令有:exec、file、open、close、read、write、puts、gets、flush、seek、tell、glob、pwd、cd、exit、pid和registry命令。
1exec
exec 命令从 Tcl 解释器中运行其它进程。
exec 命令和从 unix shell 命令行或者 unix shell 脚本中调用一个进程相似。它支持命令的输入、输出重定向,支持管道操作等。可将被调用程序的输出作为 exec 命令的值予以返回。
对于学习过 unix shell 中标准输入、输出的读者一定知道,每个进程通常有三个与之相关联I/O 管道:标准输入、标准输出和标准错误输出。通过 I/O 重定向,可以更改这三个管道的传送方向,比如可以将进程的标准输出定位到一个文件,则进程的所有标准输出信息都会保存到这个文件内。而通过管道可以组织一个进程链:一个程序的标准输出被通过管道挂接到另外一个程序的标准输入,这样管道可以将任意数目的程序连接起来一起执行。
上例使用 exec 来执行两个程序,第一个是 sort,它的标准输入被用输入重定向符””输出到用户目录下的 errorInfo.tcl 文件中。
语法:exec ?switches? arg1 ?arg2? ... ?argN?
2pid
pid 命令返回当前进程的 ID。进程 ID 在每次进程调用时的值都会改变,所以可以用进程 ID作为随机数生成的种子(seed)。也可以通过 pid 来查出与进程管道相关联的进程 ID。
3open
open 命令用于打开文件。返回一个可以供其他文件操作命令操作文件的文件描述符fileId。
语法:open fileName ?access? ?permission?。
其中 fileName 是用于打开的文件名access 是文件存取模式,默认为读操作。
permission 是一个八进制整数,用于设置文件的访问权限,默认为 rw-rw-rw(0666)。UNIX 系统将文件用户分成三类:属主( master,文件的创建者)、组用户( group users)和其他用户( other users)。每类用户设置三位文件访问权限控制标识,分别指定了读、写和执行权限。如果对应位置为”-“,则表示此类用户没有对应的访问权限。在 UNIX 系统中,可以通过 chmod 命令来更改文件的访问控制权限。
在使用 open 命令打开文件的时候,可以使用 catch 命令来捕获错误信息。这样会使代码更安全。当调用成功时,文件描述符被保存到 catch 的变量中,否则 catch 变量保存错误信息。
补充,用于变元access的POSIX的标志的总结。
标志 | 说明 |
RDONLY | 打开用于读操作 |
WRONLY | 打开用于写操作 |
RDWR | 打开用于读和谐操作 |
APPEND | 打开用于追加 |
CREAT | 如果文件不存在的话就创建 |
EXCL | 如果同时指定了CREAT,那么文件已经存在的情况下打开就会失败 |
NOCTTY | 阻止终端设备成为控制终端 |
NONBLOCK | 执行打开操作时不阻塞 |
TRUNC | 如果文件存在的话就截断 |
4 glob
glob 命令和 UNIX 系统的 ls 命令相似,用于文件的匹配搜索,并返回一个与搜索模式匹配的文件名列表。glob 支持通配符。
语法:glob ?switches? pattern ?patternN?
witches 选项有:-nocomplain 当返回空列表时, glob 不报错,不用此选项时, glob 会在返回空列表时报错。-directory directory 在指定的目录中搜索。如 glob –directory e:masm e1.tcl-path pathVar 在指定路径内搜索。不可以和-directory 同时使用。-- 结束 switches
glob 的匹配模式与 string match 命令的匹配规则相似:“*” 通配 0 或多个字符;{a,b,...}匹配 a,b ,...中的任一个字符;“?”通配单个字符;[abc]匹配一组字符;如果 pattern 开始两个字符是~/,则~将被用户路径环境变量值 HOME 替代,如果文件是以~开始,最好加一个./前导来避免这种扩展(如./~foo)。
5file及其子命令
lstat 和 stat 返回一组文件属性信息,并以数组形式保存。如果文件是一个符号链接,则lstat 返回链接本身信息, stat 返回链接目标信息。符号连接(symbol link)只将链接指向目标文件存储域,而硬链接将目标文件内容也拷贝到自己文件内,相当也作了一次拷贝。
6puts
puts命令向输出通道写入一个字符串和一个换行符。它接收一个用来阻止通常要追加到输出通道中的换行符的-nonewline变元。下面的输入提示例子中就用到了它。另一项功能就是通道标识符是可选的,在没有指定时默认为stdout。注意,你必须使用flush来强迫部分行的输出。
7get
get命令读取一行输入,而且有两种形式。只带一个变元,gets返回从指定I/O通道中读取的行。它忽略返回值中的换行符,如果达到文件末尾,就会返回一个空字符串。你必须使用eof命令来区分是空行还是文件结尾,如果是文件结尾eof就返回1.若给定第二个变元VarName,gets就将行内容存储到命名的变量中并返回读取的字节数。它丢弃尾部的换行符。计数并不将换行符考虑在内。如果通道到达了文件结尾就会返回-1.
8read
read命令成块的读取数据。这种性能通常更为高效。read有两种形式,你可以指定-nonewline变元或numBytes变元。但不能同时指定这两个变元。不带numByte,它就会读取并返回整个文件(或I/O通道中剩余的部分)给定一个字节记数变化,read就会返回那个数量的信息。或是在通道中没有足够数据时返回较少的内容。这种情况下。不丢弃末尾的换行符号。
9应用:在ICC2中利用对文件的读写操作fix drv violation
在当前目录下有一个trans cap的报告,报告格式如下,不考虑违例大小和引起违例的因素,先快速size一把驱动cell降量。
报告中包含违例点(pin),实际值,约束值和违例大小四项信息。已知当前设计的标准单元库为如下格式:INVD1HDBSVT11(SVT11的反向器,其中INV代表逻辑功能为反向器;D1为驱动大小,可以理解为晶体管的数量;SVT代表栅极阈值电压为标准电压;11代表栅极宽度为11微米)
set current_path [pwd]
set FileId [open ./trans_cap.rpt r 0750]
set rpt_context [split [read $FileId] ]
close $FileId
set rpt_context [lreplace $rpt_context first first]
set rpt_context [lreplace $rpt_context last last]
foreach pin $rpt_context {
set drive_cell [get_cells -of_object [get_pins [all_connected -leaf [get_nets -of_objects $pin -physical_contxt]] -filter “direction==out”]]
set full_name [get_attribute [get_cells $drive_cell] full_name]
set ref_name [get_attribute [get_cells $drive_cell] ref_name]
regexp {(.*)D(d+)HDB(.*)} $ref_name match ref_base_name ref_drive_level ref_vt_level
##一般驱动大小为偶数的lib cell存在,奇数驱动的不一定存在,所以提前判断一下
if { [expr ${ref_drive_level}%2 ]== 0 } {
set new_ref_drive_level [expr $ref_drive_level + 2]
set new_ref_name ${ref_base_name}D${new_ref_drive_level}HDB${ref_vt_level}
size_cell $full_name $new_ref_drive_level
} else {
set new_ref_drive_level [expr $ref_drive_level + 1]
set new_ref_name ${ref_base_name}D${new_ref_drive_level}HDB${ref_vt_level}
size_cell $full_name $new_ref_drive_level
}
}