[racket] Duplicating output from a system call

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Thu May 16 19:00:05 EDT 2013

I tried your code with this bash script:

#!/bin/sh
echo hi
sleep 1
echo bye

and I saw the "hi" a bit before the "bye" and the results printout. Is it
possible your script is not flushing its output?

Also I agree with Neil that process*/ports is going to be better in the
general case: it is more flexible than system (but if system* works, that
can be okay: it is only obviously better than process*).

Robby



On Thu, May 16, 2013 at 5:36 PM, Nick Shelley <nickmshelley at gmail.com>wrote:

> Thank you both for your responses.
>
> I tried to get Robby's to work because it seemed a little simpler, but I
> think I'm having buffering problems. I could have completely misunderstood
> the proposed solution as well...
>
> Here's the relavent code:
>
>   (define-values (in out) (make-pipe))
>   (define stdout (current-output-port))
>   (define string-port (open-output-string))
>   (thread (λ () (copy-port in stdout string-port)))
>   (thread (λ () (flush-output stdout)))
>   (parameterize ([current-output-port out])
>     (system <script-that-logs-to-console>))
>   (printf "~n~nresults: ~a~n" (get-output-string string-port))
>
> What I get is nothing until the script finishes, then I get the log
> message from stdout followed by my "results: ..." message that contains a
> duplicate of the logs. This is exactly what I want except that I want the
> logs to the stdout port to print in real time. I added the flush-output
> thread as an attempt to get around buffering, but I'm obviously
> misunderstanding something because it still didn't work.
>
>
> On Thu, May 16, 2013 at 2:24 PM, Robby Findler <
> robby at eecs.northwestern.edu> wrote:
>
>> I find that using make-pipe with copy-port works well. Often you need to
>> create a thread that copies the data to the real port you want it to go to
>> and then stdout (or whatever) and when you do that, you have to be careful
>> to make sure ports get closed properly, or else you'll lose data, but it
>> doesn't take much code and works well.
>>
>> Robby
>>
>>
>> On Thu, May 16, 2013 at 3:12 PM, Nick Shelley <nickmshelley at gmail.com>wrote:
>>
>>> I have a script that runs some automated tests and logs the results to
>>> the console. The tests can take 10+ minutes, so logging steps to the
>>> console is informative. I'm using Racket to run the script with (system
>>> ...) and parse the logs and report pass/failure, but to do that I have to
>>> capture the logs. I spent about an hour in the port docs and can't figure
>>> out how to both log to the console and capture the logs in Racket for
>>> further processing (although I'm really good at missing the obvious).
>>>
>>> My current workaround is to use the tee command when running the script
>>> and then read in and process the file afterwords, but I was wondering if
>>> there is a more direct way to do this in Racket.
>>>
>>> ____________________
>>>   Racket Users list:
>>>   http://lists.racket-lang.org/users
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130516/15a859c5/attachment.html>

Posted on the users mailing list.