将 tcl proc 的输出重定向到文件和输出(如 tee)第 2 部分

Redirecting output of tcl proc to file and output (like tee) Part 2

我正在使用 https://wiki.tcl-lang.org/page/Tee 的 tee 来重定向我程序的文件输出。我需要将 stdout 和 stderr 都重定向到文件。

使用来自 的输入,我完成了以下操作:

    set LogFile  [open ${LogFileName} w]
    tee channel stderr $LogFile
    tee channel stdout $LogFile
    set BuildErrorCode [catch {LocalBuild $BuildName $Path_Or_File} BuildErrMsg]
    set BuildErrorInfo $::errorInfo
    
    # Restore stdout and stderr 
    chan pop stdout
    chan pop stderr

   # Handle errors from Build ...

我正在三种不同的 EDA 工具上对此进行测试,我遇到了三个不同的问题。

  1. 当我从 tclsh 运行(在 Windows 10 上的 MSYS2 运行ning 上)和 运行 开源模拟器 GHDL、ModelSim 或 QuestaSim 时,所有偶数字符是 NUL 字符。
  2. 如果我从 GUI 运行 ModelSim 或 QuestaSim,我会错过每个命令的输出。那不应该去 stdout 或 stderr 吗?
  3. 在 Riviera-PRO 中,我收到了之前打印的无关字符。它们通常是一个单词的后半部分。

我做错了什么吗?我使用以下代码测试了上面的代码:

set LogFile  [open test_tee.log w]
tee channel stderr $LogFile
tee channel stdout $LogFile

puts "Hello, World!"
puts stderr "Error Channel"
puts stdout "Output Channel"

chan pop stdout
chan pop stderr

这很有效。

我希望找到适用于所有工具的一般情况的东西,而不是必须为每个工具编写不同的处理程序。

============更新=============
对于上面的#1,根据@Shawn 的建议,我尝试了以下方法,但没有用。

    set LogFile  [open ${LogFileName} w]
    chan configure $LogFile -encoding ascii
    . . .

我也尝试了以下方法,但没有用。

    set LogFile  [open ${LogFileName} w]
    fconfigure $LogFile -encoding ascii
    . . .

然后我尝试将 tee 中的 write 更新为以下内容,但没有成功:

proc tee::write {fd handle buffer} {
    puts -nonewline $fd [encoding convertto ascii $buffer]
    return $buffer
}

感谢任何其他提示解决方案

============更新2 =============
我已经通过执行以下操作成功删除了 nul 字符,除了现在我有一个额外的换行符。仍然不是解决方案。

proc tee::write {fd handle buffer} {
    puts -nonewline $fd [regsub -all \x00 $buffer ""]
    return $buffer
}

额外的 NUL 字节可能是因为 stdout ahd 引导通道是用 UTF-16 编写的(该编码的主要用途是 Windows 上的控制台)。您正在使用的 tee 拦截器是在对写入的数据进行编码之后出现的。有几种方法可以修复它,但最简单的方法是在读取文件时使用正确的编码打开文件。

命令的输出不一定写入那些通道。用C或C++编写的代码完全可以直接自由编写,而Tcl代码看不到这一点;这一切都发生在我们背后。 Command results 可以使用执行跟踪来拦截,但是它看不到命令​​内部打印的任何内容,这些内容不是通过 Tcl 库以某种方式路由的。 (由于 OS 处理 I/O 的方式不同,Unix 上还有更多选项。)

不知道多余的字符是怎么回事。我可以告诉你,你正在获取通过频道的内容,但是有太多的技巧(尤其是在交互式使用中!)无法在这方面进行有用的猜测。