3
votes

I have a tclsh script in which I needed to execute certain command in background. I could achieve this from tcl using exec command: exec myprog &.

But how can I wait for myprog to complete from tcl. The command wait is not a standalone utility so I can use it with exec. The wait command is a shell builtin. Please let me know how can I wait for the background process in tclsh script.

PS: I am using #!/usr/bin/env tclsh shebang in my script.

1
@rkosegi: Presumably the command no longer executes in the background.zrvan
If I remove &, the command executes and returns once myprog is completed... so no question of wait at all...Mallik

1 Answers

3
votes

If you want to execute a command in the background in Tcl, you could go for something along the line of:

proc cb { fd } {
        gets $fd buf
        append ::output $buf
        if {[eof $fd]} {
            close $fd
            set ::finished 1
        }
}

set command "<command to execute>"
set ::output ""
set ::finished 0
set fd [open "|$command" r]
fconfigure $fd -blocking no
fileevent $fd readable "cb $fd"
vwait ::finished
puts $::output

The use of open with a | before the command will allow you to "open" a pipe to the command. Using fconfigure to set it non-blocking will allow you to read from it without locking any other process in the script. fileevent will call the specified callback proc (in this case cb) whenever there's data to be read (thus the readable flag). vwait will make sure the script does not proceed until the specified variable is written to, thus the $command will be executed in the background, allowing say a Tk interface to remain responsive and waiting until you want to continue.