Tcl中exec命令的2>@stdout是否与2>@1效果一致?
问题原因解答
这是Tcl exec命令在被变量捕获输出场景下的正常行为,核心逻辑如下:
- 当你把
exec命令放在[]中并赋值给变量时,exec会临时把调用进程的stdout文件标识符重定向到内部管道,用来收集子进程的标准输出内容,作为exec的返回值塞给变量。这时候你代码里用到的stdout指向的是这个临时管道,不是原本的终端标准输出。 - 你的第一组测试用了
2>@stdout,相当于把子进程的标准错误也重定向到了这个收集用的临时管道,所以子进程的标准输出、标准错误都进了管道,最终都赋值给output变量写入日志,终端自然没有任何输出,和你看到的现象一致。 - 你的第二组测试用了
2>@stderr,exec在捕获输出的场景下不会修改调用进程的stderr标识符,它还是指向终端,所以子进程的标准错误直接输出到终端,只有标准输出被管道收集赋值给变量,符合文档描述的预期。
你可以做个简单验证:去掉变量捕获逻辑,直接在Tcl交互环境执行exec bash -c "1>&2 echo warning; echo usual output" 2>@stdout,此时没有输出捕获,stdout仍然指向终端,你会看到两行内容都直接打印到屏幕,完全符合官方文档的原始说明。
如果需要在捕获子进程标准输出的同时,把子进程的标准错误打到父进程原本的标准输出(终端),可以提前备份父进程的标准输出标识符:
set orig_stdout [dup stdout] set output [exec bash -c "1>&2 echo warning; echo usual output" 2>@$orig_stdout]
内容的提问来源于stack exchange,提问作者Larry
相关产品推荐
相关产品推荐

