我有这个脚本,想并行运行exec。目前它正在一个接一个地运行。我该怎么办?
非常感谢您的帮助
bind pub -|- !tt proc:tt
proc proc:tt {nick host handle channel arg} {
set search [lindex [split [stripcodes bcu $arg]] 0]
foreach name {name1 name2 name3 name4 name5} {
set results [exec sh search.sh $name $search]
putnow "PRIVMSG $channel :results: $results"
}
}
此问题已陆续出现。但应该是平行的
[24.02.20/22:00:59] <testbot> results: /home/test/name1
[24.02.20/22:01:34] <testbot> results: /home/test/name2
[24.02.20/22:03:05] <testbot> results: /home/test/name3
[24.02.20/22:09:05] <testbot> results: /home/test/name4
[24.02.20/22:09:07] <testbot> results: /home/test/name5
答案 0 :(得分:2)
要在后台运行命令并捕获结果,您需要打开管道并异步运行。 (如果exec
是最后一个参数,则&
命令可以在后台运行事物,但在捕获结果时则不能。)
bind pub -|- !tt proc:tt
proc proc:tt {nick host handle channel arg} {
set search [lindex [split [stripcodes bcu $arg]] 0]
foreach name {name1 name2 name3 name4 name5} {
# Launch the subprocess
set pipe [open |[list sh search.sh $name $search]]
# Set up a handler for when the subprocess produces *any* output *or* finishes
fconfigure $pipe readable [list handle:search:output $channel $pipe $name]
}
putnow "PRIVMSG $channel processing..."
}
proc handle:search:output {channel pipe name} {
set line [gets $pipe]
if {[eof $pipe]} {
close $pipe
putnow "PRIVMSG $channel search for $name done"
return
}
putnow "PRIVMSG $channel :result($name): $line"
}
请注意,这将并行启动所有搜索。这可能会使您的系统负担很多!这也可能以任意顺序传递结果。可以按 顺序执行操作,但需要使用手动继续传递的更复杂代码或协程(Tcl 8.6或更高版本)。或者,您可以按顺序将处理工作交给子流程:很简单。
答案 1 :(得分:0)
请参见https://tcl.tk/man/tcl8.6/TclCmd/exec.htm
如果最后一个arg是
&
,则管道将在后台执行。在这种情况下,exec命令将返回一个列表,其元素是管道中所有子流程的流程标识符。如果尚未重定向,则管道中最后一条命令的标准输出将转到应用程序的标准输出,并且除非重定向,否则管道中所有命令的错误输出将转到应用程序的标准错误文件。