TCL:无法将数据写入文件

TCL:无法将数据写入文件,tcl,Tcl,我正在尝试将消息写入现有文件。 执行检查以查看某些变量值,然后将相应的消息附加到文件,但$data value不会写入文件。 请让我知道我的代码有问题吗 proc run_sanity {} { global rundir typep corner_name reflib compLib cd $rundir set filename "sanity.txt" set fileId [open $filename "w"] if {[file exists

我正在尝试将消息写入现有文件。 执行检查以查看某些变量值,然后将相应的消息附加到文件,但$data value不会写入文件。 请让我知道我的代码有问题吗

proc run_sanity {} {
    global rundir typep corner_name reflib compLib
    cd $rundir
    set filename "sanity.txt"
    set fileId [open $filename "w"]
    if {[file exists $filename]} {
        exec rm -rf $rundir/sanity.txt
    }
    exec grep operating_conditions -A 3 $compLib | grep -v default | grep -v lu | grep -v variable > $rundir/sanity.txt
    exec grep nom $compLib >> $rundir/sanity.txt
    exec grep library $compLib | grep -v slew | grep -v features >> $rundir/sanity.txt
    set driver [exec grep -c driver_waveform $compLib]
    set recovery [exec grep -c recovery $compLib]
    set removal [exec grep -c removal $compLib]
    if {$driver > 0 && $recovery > 0 && $removal > 0} {
        set data "No data found for Driver waveform, Recovery and Removal Table.\n"
        puts $fileId $data
    } else {
        set data "Driver waveform, Recovery and Removal table is present in .lib.\n"
        puts $fileId $data
    }
    close $fileId
    exec emacs $rundir/sanity.txt &
}
谢谢
Dan基本上,您的代码是

set fileId [open $filename "w"]      ; 1
if {[file exists $filename]} {       ; 2
    exec rm -rf $rundir/sanity.txt   ; 3
}
puts $fileId $data                   ; 4
所以

打开文件进行写入

w模式确保在文件不存在时创建该文件 或者被截断,如果是这样的话

然后检查文件是否存在

由于第一步,该检查始终通过 除非您在文件系统上与其他人竞争 在执行此检查之前,请先删除文件

您可以删除该文件

因为这应该发生在具有POSIX语义的文件系统上 也就是说,在某些Unix-y操作系统上,任何打开到该操作系统的文件描述符 已删除的文件将计为对该文件的实时引用,因此 条目已从文件系统的目录中删除,但其数据未被删除, 读取和写入这些数据是正常的,只是 无法在进程之外访问,因为此数据不再具有任何 文件系统上的名称

顺便说一下,Unix软件经常使用这个技巧来保持 临时数据:创建一个文件,然后立即从中删除 文件系统,同时保持打开的文件描述符

您可以写入该文件。写入操作正常,数据实际上是 存储在文件系统中

一旦关闭文件,其数据将丢失对该文件的最后一次实时引用 就在那个时候,数据被删除了

因此,您应该重新考虑管理此文件的方法。 到目前为止,处理sanity.txt几乎没有什么理智可言-


顺便问一下,为什么要使用rm-rf和why-r?而不是仅仅从Tcl中删除文件?这会快一点。

这段代码在我将fileId移动到if循环中时起作用,同时考虑POSIX语义

proc run_sanity {} {
global rundir typep corner_name reflib compLib
cd $rundir
set Sname "sanity.txt"
##set fileId [open $filename "a"]
if {[file exists $Sname]} {
file delete $rundir/sanity.txt
}
after 10000 {destroy .dialog4}
   tk_dialog .dialog4 "Running Sanity:" "SANITY TEST RUNNING" info 0 OK
exec grep operating_conditions -A 3 $compLib | grep -v default | grep -v lu | grep -v variable > $rundir/sanity.txt
exec grep nom $compLib >> $rundir/sanity.txt
exec echo "" >>  $rundir/sanity.txt
exec grep library $compLib | grep -v slew | grep -v features >> $rundir/sanity.txt
exec echo "" >>  $rundir/sanity.txt
set driver [exec grep -c driver_waveform $compLib]
set recovery [exec grep -c recovery $compLib]
set removal [exec grep -c removal $compLib]
cd $rundir
if {$driver > 0 && $recovery > 0 && $removal > 0} {
set filename "sanity.txt"
set fileId [open $filename "a"]
set msg "Driver waveform, Recovery and Removal table is present in .lib.\n"
puts $fileId $msg
close $fileId
} else {
set filename "sanity.txt"
set fileId [open $filename "a"]
set msg "No data found for Driver waveform, Recovery and Removal Table.\n"
puts $fileId $msg
close $fileId
}
exec emacs $rundir/sanity.txt &
}

谢谢kostix,你在我的代码中发布了一些真正的问题。我修复了如下代码,现在可以正常工作了。