Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting output from a process immediately

99 views
Skip to first unread message

Cecil Westerhof

unread,
Jul 8, 2018, 5:14:05 AM7/8/18
to
At the moment I have the following:
puts [exec ${pip} install --no-cache-dir --upgrade {*}${packages}]

But this shows the output only after the command is finished.
What is the best way to show the output when it comes available?

--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

Brad Lanam

unread,
Jul 8, 2018, 7:33:10 AM7/8/18
to
If there are multiple lines of output, you can use a pipe.

proc myproc {fh} {
if { [gets $fh line] >= 0 } {
puts $line
flush stdout
}
}

set cmd [list ${pip} install --no-cache-dir --upgrade {*}$packages]
set fh [open |$cmd r]
fconfigure $fh -blocking nonblocking
fileevent $fh readable [list ::myproc $fh]

It's a bit messier than this, you will need to check for
end-of-file on $fh.

Looks like I have only one left in my program.
I think in my case, I have it there because the program
cannot be synchronous at that point,
and must be event driven.
Someday I will change it to use a socket.


Cecil Westerhof

unread,
Jul 8, 2018, 8:59:05 AM7/8/18
to
At the moment I have:
set params "install --no-cache-dir --upgrade ${packages}"
set pipPipe [open "|${pip} ${params}" RDONLY]
while {-1 != [gets ${pipPipe} line]} {
puts ${line}
}
close ${pipPipe}

Would that not be OK? (Can only check when I need a pip update.)

You use '>= 0' instead of '!= -1'. Is that necessary?
Is the flush from stdout necessary?

Brad Lanam

unread,
Jul 8, 2018, 9:08:27 AM7/8/18
to
On Sunday, July 8, 2018 at 5:59:05 AM UTC-7, Cecil Westerhof wrote:
That looks fine.
I put the flush in as you said "show the output when it comes available".
So I wanted to make sure the output was displayed.

% fconfigure stdout
...-buffering line...

Looks like stdout is set for line buffering, so the flush probably is
not necessary. Tcl is probably already doing it.

Cecil Westerhof

unread,
Jul 8, 2018, 10:44:05 AM7/8/18
to
I just have to wait until an update is necessary. ;-)

Christian Gollwitzer

unread,
Jul 8, 2018, 4:14:30 PM7/8/18
to
Am 08.07.18 um 15:08 schrieb Brad Lanam:
> On Sunday, July 8, 2018 at 5:59:05 AM UTC-7, Cecil Westerhof wrote:
>> At the moment I have:
>> set params "install --no-cache-dir --upgrade ${packages}"
>> set pipPipe [open "|${pip} ${params}" RDONLY]
>> while {-1 != [gets ${pipPipe} line]} {
>> puts ${line}
>> }
>> close ${pipPipe}
>>
>> Would that not be OK? (Can only check when I need a pip update.)
>>
>> You use '>= 0' instead of '!= -1'. Is that necessary?
>> Is the flush from stdout necessary?
>
> That looks fine.


...unless it is running in a GUI. When you do GUI, then this loop will
run until the process is finished and meanwhile the event loop can't
process any events, which means that the screen is not repainted or on
Windows, you can't even move the window.

Christian

Cecil Westerhof

unread,
Jul 8, 2018, 5:44:04 PM7/8/18
to
It is just a command-line script. When I feel the need to make a GUI
version I will look into it again.

Robert Heller

unread,
Jul 8, 2018, 6:48:41 PM7/8/18
to
When you do, you should look at fileevent...

>

--
Robert Heller -- 978-544-6933
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

heinrichmartin

unread,
Jul 9, 2018, 3:30:15 AM7/9/18
to
Avoid busy waiting. It's not just about the GUI remaining responsive ...

On Sunday, July 8, 2018 at 4:44:05 PM UTC+2, Cecil Westerhof wrote:
> I just have to wait until an update is necessary. ;-)

Look into the man pages of pip. Most package managers provide command line options to make such checks more efficient and provide the result in the exit code. No need to parse the output, you could even run it in quiet mode.

On the other hand, when parsing (or even interacting) with other processes, you might want to consider Expect.

Cecil Westerhof

unread,
Jul 9, 2018, 4:44:04 AM7/9/18
to
heinrichmartin <martin....@frequentis.com> writes:

> On Sunday, July 8, 2018 at 4:44:05 PM UTC+2, Cecil Westerhof wrote:
>> I just have to wait until an update is necessary. ;-)
>
> Look into the man pages of pip. Most package managers provide command
> line options to make such checks more efficient and provide the result
> in the exit code. No need to parse the output, you could even run it in
> quiet mode.
>
> On the other hand, when parsing (or even interacting) with other
> processes, you might want to consider Expect.

My script determines what has to be updated and then does that. And I
really want to see what is happening. (I could make a switch for not
displaying anything for people who are not interested in the output.)

It determines for example that for pip3 pckgA, pckgB and pckgC need to
be updated. It then executes:
pip3 pckgA pckB pckC

Because this can take a while, I do not like to see all output at the
moment the command is ready, but see everything at the moment it comes
available. As if I put in the command myself. ;-)

Uwe Klein

unread,
Jul 9, 2018, 9:00:08 AM7/9/18
to
Am 08.07.2018 um 11:04 schrieb Cecil Westerhof:
> At the moment I have the following:
> puts [exec ${pip} install --no-cache-dir --upgrade {*}${packages}]
>
> But this shows the output only after the command is finished.
> What is the best way to show the output when it comes available?
>
the bgexec command from blt was very useful in that respect.
no idea if this has made it into the rbc ( refactored blt ) package.

http://soc.if.usp.br/manual/blt/html/bgexec.html

Uwe

Ralf Fassel

unread,
Jul 16, 2018, 9:32:43 AM7/16/18
to
* Cecil Westerhof <Ce...@decebal.nl>
| It determines for example that for pip3 pckgA, pckgB and pckgC need to
| be updated. It then executes:
| pip3 pckgA pckB pckC
>
| Because this can take a while, I do not like to see all output at the
| moment the command is ready, but see everything at the moment it comes
| available. As if I put in the command myself. ;-)

Consider simply redirecting the output of exec:

exec pip3 pckgA pckB pckC >@stdout 2>@stderr

This will still block your TCL program, but since you do nothing anyway
but waiting for pip3 to finish...

HTH
R'

lmn...@gmail.com

unread,
Jul 16, 2018, 8:07:57 PM7/16/18
to
On Monday, July 9, 2018 at 1:44:04 AM UTC-7, Cecil Westerhof wrote:
I'll re-mention Expect

Try the "spawn" and "interact" commands provided by Expect to see output immediately.

Example:
#! /usr/bin/env expect
spawn <insert exec call here>
interact
# eof
0 new messages