Reputation: 1
i have this script and want to run the exec in parallel. at the moment it is running one after another. How do I do that?
Many thanks for your help
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"
}
}
at the moment the issue is in succession. but it should be parallel
[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
Upvotes: 0
Views: 504
Reputation: 137567
To run a command in the background and capture the results, you need to open a pipeline and run things asynchronously. (The exec
command can run things in the background if &
is its final argument, but not while capturing the results.)
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"
}
Note that this launches all the searches in parallel. This might load your system up quite a bit! This may also deliver results in an arbitrary order. Doing things in order is possible, but requires either more complicated code with manual continuation passing, or coroutines (Tcl 8.6 or later). Or you can hand off the doing things in sequence to a subprocess: that's easy.
Upvotes: 2
Reputation: 246774
See https://tcl.tk/man/tcl8.6/TclCmd/exec.htm
If the last arg is
&
then the pipeline will be executed in background. In this case the exec command will return a list whose elements are the process identifiers for all of the subprocesses in the pipeline. The standard output from the last command in the pipeline will go to the application's standard output if it has not been redirected, and error output from all of the commands in the pipeline will go to the application's standard error file unless redirected.
Upvotes: 0