将 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 工具上对此进行测试,我遇到了三个不同的问题。
- 当我从 tclsh 运行(在 Windows 10 上的 MSYS2 运行ning 上)和 运行 开源模拟器 GHDL、ModelSim 或 QuestaSim 时,所有偶数字符是
NUL
字符。
- 如果我从 GUI 运行 ModelSim 或 QuestaSim,我会错过每个命令的输出。那不应该去 stdout 或 stderr 吗?
- 在 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 上还有更多选项。)
不知道多余的字符是怎么回事。我可以告诉你,你正在获取通过频道的内容,但是有太多的技巧(尤其是在交互式使用中!)无法在这方面进行有用的猜测。
我正在使用 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 工具上对此进行测试,我遇到了三个不同的问题。
- 当我从 tclsh 运行(在 Windows 10 上的 MSYS2 运行ning 上)和 运行 开源模拟器 GHDL、ModelSim 或 QuestaSim 时,所有偶数字符是
NUL
字符。 - 如果我从 GUI 运行 ModelSim 或 QuestaSim,我会错过每个命令的输出。那不应该去 stdout 或 stderr 吗?
- 在 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 上还有更多选项。)
不知道多余的字符是怎么回事。我可以告诉你,你正在获取通过频道的内容,但是有太多的技巧(尤其是在交互式使用中!)无法在这方面进行有用的猜测。