Thomas Danckaert
2018-05-24 08:10:22 UTC
Hi Guilers,
I want to run an external process, and capture both its stdout and
stderr output streams. I didn't find an easy way to get a port for
an external process' stderr, other than wrapping the call to the
process in "with-error-to-port".
My questions are:
0) Did I miss something obvious? :)
1) why doesn't the second approach in the code below work (the
output-string is always empty)?
2) are there any other (better) solutions?
3) I suppose my approach with (pipe) might block if the process
writes too much data to stderr before I read from the pipe. Should I
use "select" to interleave reads from stdout and stderr?
thank you!
Thomas
(use-modules (ice-9 format)
(ice-9 popen)
(ice-9 textual-ports))
(define (run-command)
(let ((process (open-input-pipe "./stdoutstderr.sh")))
(format #t "stdout: '~a'~%" (get-string-all process))
(close-pipe process)))
;; Works:
(let ((err-pipe (pipe)))
(with-error-to-port (cdr err-pipe) run-command)
(close-port (cdr err-pipe))
(format #t "stderr: '~a' ~%" (get-string-all (car err-pipe))))
;; Doesn't work: (get-output-string) returns empty string.
(let ((err-port (open-output-string)))
(with-error-to-port err-port run-command)
(format #t "stderr: '~a'~%" (get-output-string err-port))
(close-output-port err-port))
I want to run an external process, and capture both its stdout and
stderr output streams. I didn't find an easy way to get a port for
an external process' stderr, other than wrapping the call to the
process in "with-error-to-port".
My questions are:
0) Did I miss something obvious? :)
1) why doesn't the second approach in the code below work (the
output-string is always empty)?
2) are there any other (better) solutions?
3) I suppose my approach with (pipe) might block if the process
writes too much data to stderr before I read from the pipe. Should I
use "select" to interleave reads from stdout and stderr?
thank you!
Thomas
(use-modules (ice-9 format)
(ice-9 popen)
(ice-9 textual-ports))
(define (run-command)
(let ((process (open-input-pipe "./stdoutstderr.sh")))
(format #t "stdout: '~a'~%" (get-string-all process))
(close-pipe process)))
;; Works:
(let ((err-pipe (pipe)))
(with-error-to-port (cdr err-pipe) run-command)
(close-port (cdr err-pipe))
(format #t "stderr: '~a' ~%" (get-string-all (car err-pipe))))
;; Doesn't work: (get-output-string) returns empty string.
(let ((err-port (open-output-string)))
(with-error-to-port err-port run-command)
(format #t "stderr: '~a'~%" (get-output-string err-port))
(close-output-port err-port))