当您使用(由于与您的问题无关exec $executable {*}$options >@ stdout
的原因而首选您正在使用的更安全的版本)时,您要求将子进程的输出直接发送到外部进程的标准输出,而无需进一步加工。如果您想先处理更多内容,则必须先通过过滤过程引导输出,然后再将其引导到 stdout,或者将其带入外部进程进行处理。
构建过滤管道
在这种情况下,我们使用 Unix 程序sed
进行过滤:
exec $executable {*}$options | sed {s/world/tcl/} >@ stdout
做这种事情有很多选择;sed
只要您记得您使用的是 Tcl 语法exec
而不是 shell 语法,那么许多方法中的任何一种都将(可能)起作用,所以不要sed 's/world/tcl/'
使用sed {s/world/tcl/}
.
如果您更喜欢 shell 语法,请执行以下操作:
set filter "sed 's/world/tcl/'"
exec $executable {*}$options | sh -c $filter >@ stdout
中的脚本$filter
是纯 Bourne shell。
Tcl 内部处理
您也可以在 Tcl 中进行转换。为此,您需要在打开的管道上异步工作。
# Define this procedure somewhere
proc transformLine {chan transform} {
if {[gets $chan line] >= 0} {
puts [string map $transform $line]
} elseif {[eof $chan]} {
catch {close $chan} ::doneWithPipe
}
}
set pipe [open "|$executableName $options"]
fileevent $pipe readable [list transformLine $pipe {"world" "tcl"}]
vwait ::doneWithPipe
return -code error $::doneWithPipe
请注意,您必须运行事件循环(使用vwait
)才能使其正常工作。