DrDr has some reusable, robust code for capturing output and sequence stderr/stdout:
https://github.com/plt/racket/blob/master/collects/meta/drdr/run-collect.rkt Jay 2011/2/6 Neil Van Dyke <n...@neilvandyke.org>: > Thomas Chust wrote at 02/06/2011 10:14 AM: > > 2011/2/6 Manfred Lotz <manfred.l...@arcor.de>: > > > [...] > I don't know how to merge stdout and stderr in proper sequence. > [...] > > > There is no such thing as proper sequencing of data flowing through > different streams. > > Due to buffering in system libraries and the operating system kernel it is > also entirely impossible to reliably process the output data in the exact > sequence it was produced by the external process. > > Agreed with Thomas that doing this perfectly is impossible in the general > case, even when there's a single-threaded producer of the two streams. > > However, if you want to sequence reading stdout and stderr close enough for > most purposes, keep in mind that these are usually interleaved at the > resolution of lines rather than characters, so you can get this pretty much > right, and still do fairly efficient block reads. So, you can do the > sequencing efficiently in your reading process by doing raw stdio and > avoiding any buffering port abstractions in your library, doing a "sync" > loop on the ports, and implementing your own buffering for each port, out of > which buffer you pick a complete line at a time. You also can tweak this to > better interleave reads from the two streams/buffers. You can also use time > or other heuristics to detect when, say, a stdout message like > "Processing..." without newline should be handled because it was interrupted > by a subsequent stderr error message. There might still be buffering > outside of your control, but I think it doesn't often matter. > > Once you get into "expect"-like interaction with a process using the three > streams at once, and doing pattern-matching while also capturing the output, > and doing this all efficiently, it's tricky. There's no reason that a > generalized library routine to do this can't be implemented in Racket, but > I'm not aware of one. If you hand-implement for a particular purpose, I > think you'll be getting your hands dirty with "sync", your own buffering of > both input and output, block I/O, and some strategy for how to do your > pattern-matching efficiently on the buffers. IMHO, this should feel like > systems programming if you're doing it efficiently. This complication does > not reflect a limitation of Racket, but instead that Racket is flexible > enough that this doing this complicated stuff is possible. > > -- > http://www.neilvandyke.org/ > > > _________________________________________________ > For list-related administrative tasks: > http://lists.racket-lang.org/listinfo/users > -- Jay McCarthy <j...@cs.byu.edu> Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users