exec - tcl exec 先读取标准输出,然后再读取标准错误?

标签 exec tcl stdout stderr

我发现 tcl exec 命令首先从标准输出返回字符串,然后是标准错误。例如,我下面的“测试脚本”按以下顺序生成消息:

puts "test started"
puts stderr "some non-fatal error goes to stderr"
puts "test passed"

然后我像这样执行脚本:
set ret [ catch { exec sh -c $cmd } msg ]

我从 $msg 得到的是:
test started
test passed
some non-fatal error goes to stderr

这真的让我很难得到正确的结果。

有人可以知道是否可以按顺序从 stdout 和 stderr 获取消息,并且:

1)请不要像这样重定向,这确实可以让它们全部有序:
set ret [ catch {exec $cmd >&log.txt} msg ]

2)我必须在我的 tcl 脚本中调用那个 tcl 脚本,抱歉

3)我也不能直接获取 .tcl 测试脚本,因为在两者之间调用了其他脚本,如果我的 tcl 脚本只是获取该 tcl 脚本,它将无法工作。

我正在使用 tclsh 8.3

不知道这是否要求太多。我希望有人能解决这个问题。谢谢。

最佳答案

首先,让我们为测试目的定义一个简单的命令,我们可以确定将测试我们需要的内容:

set cmd "echo a; echo b >&2; echo c"

接下来,我们使用一些额外的帮助程序来处理 stdout 和 stderr 流的合并(为了清楚起见,将命令分成几行,以便我们可以看到 catch 包装器的位置以及包装的 exec 的位置):
set ret [catch {
   exec sh -c $cmd |& cat
} msg]

如果我们测试一下,我们会发现我们得到 $ret正在 0 , 和 $msg正确订购:
a
b
c

它是如何工作的?诀窍是 |& ,它在管道到另一个进程时进行合并。 (我们使用 cat 因为它只是通过而不干扰。)

如果您使用的是 Tcl 8.6(测试版),您可以使用 chan pipe 生成一个可以重定向的 channel stdoutstderr进与 2>@ fileId form ,但这对你来说不是那么有用。 (您是否知道 8.3 已经过时了?甚至 8.4 也不再真正受支持;8.5 是推荐针对的生产级代码。)

关于exec - tcl exec 先读取标准输出,然后再读取标准错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3545194/

相关文章:

python - 如何捕获通过 exec() 执行的 ZeroDivisionError 的参数?

regex - Lookbehind 和 Lookaround 概念在 TCL 正则表达式引擎中有用吗?

nested - 为什么在 tcl 中我们需要嵌套过程

c - 通过管道输入/输出到进程

perl - 如何使用 Perl 获取 DOS 工具的命令行输出?

java - 从 PHP 调用 Java 程序

java - 在android中执行管道命令

string - 如何将 Tcl 列表框数字索引转换为其元素

c++ - 将 int 转换为两个字节的数组

android - 以 root 身份运行的二进制文件的 exec() 权限被拒绝