From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Roel Janssen Newsgroups: gmane.lisp.guile.user Subject: Re: How do you record output of both STDERR and STDIN to a string? Date: Thu, 10 Sep 2020 17:04:22 +0200 Message-ID: <4ede1fc86c21609bfb45dd3f33eaa64b7df785ba.camel@gnu.org> References: <865z8mph4e.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33917"; mail-complaints-to="usenet@ciao.gmane.io" To: "Bonface M. K." , guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Thu Sep 10 17:04:49 2020 Return-path: Envelope-to: guile-user@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kGO81-0008hD-FO for guile-user@m.gmane-mx.org; Thu, 10 Sep 2020 17:04:49 +0200 Original-Received: from localhost ([::1]:58504 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kGO80-0000bO-A0 for guile-user@m.gmane-mx.org; Thu, 10 Sep 2020 11:04:48 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:35198) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kGO7e-0000YC-LO for guile-user@gnu.org; Thu, 10 Sep 2020 11:04:26 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:60389) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kGO7e-000511-A0; Thu, 10 Sep 2020 11:04:26 -0400 Original-Received: from [143.121.198.62] (port=49900 helo=cog147) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kGO7c-0002N7-Lq; Thu, 10 Sep 2020 11:04:25 -0400 In-Reply-To: <865z8mph4e.fsf@gmail.com> X-Mailer: Evolution 3.28.5-0ubuntu0.18.04.2 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.io gmane.lisp.guile.user:16900 Archived-At: On Thu, 2020-09-10 at 04:14 +0300, Bonface M. K. wrote: > Hi all. Is there a way to "record" the output from both *stderr* and > *stdout* from a guile process if you wrap it around a "system" call > to a > string? Here's something that works. It's not /exactly/ what I want > because "open-input-pipe" runs the command in a subprocess. > > --8<---------------cut here---------------start------------->8--- > (define (run-job job) > (let* ((port (open-input-pipe job)) > (str (read-line port))) > (close-pipe port) > str)) > > (display (format #t "~s ~s ~s" > "padding" > (run-job "echo hello") > "testing")) > --8<---------------cut here---------------end--------------->8--- > > I've tried out creating a fork: > > --8<---------------cut here---------------start------------->8--- > (define (run-job thunk) > (call-with-output-string > (λ (port) > (match (pipe) > ((in . out) > (match (primitive-fork) > (0 ; child > (close in) > (with-error-to-port out thunk)) > ((= waitpid (pid . exit-code)) ;; parent > (close out) > (display (read-line in) port)))))))) > > ;; Doesn't work: > (display (format #t "~s ~s ~s" > "padding" > (run-job (system "echo hello")) > "testing")) > --8<---------------cut here---------------end--------------->8--- > > Ideally for a correct output without errors, I'd like to have as > output: > > --8<---------------cut here---------------start------------->8--- > "padding" "hello" "testing" > --8<---------------cut here---------------end--------------->8--- > > and in the event I have an error, like say, by running (system > "echoooo hello"), I get > the output: > > --8<---------------cut here---------------start------------->8--- > "padding" "sh: command not found" "testing"" > --8<---------------cut here---------------end--------------->8--- > > PS: I'm new to Guile :) > Having spent a day on this myself, this is the best I had come up with: --8<---------------cut here---------------start------------->8--- (define (virtuoso-isql-query query) "Executes QUERY via ISQL and returns a both an ERROR-PORT and a PORT to read CSV output from." (let* ((tmp (getenv "TMPDIR")) (error-port (mkstemp! (string-append (if tmp tmp "/tmp") "/sg- XXXXXX"))) (port (open-input-pipe (format #f "~a ~a -U ~a -P ~a verbose=off csv_rfc4180=on csv_rfc4180_field_separator=, exec='~:a' 2> ~a" (isql-bin) (isql-port) (rdf-store- username) (rdf-store-password) (string-append "SPARQL " query) (port-filename error-port))))) (setvbuf port 'block 4096) (values error-port port))) --8<---------------cut here---------------end--------------->8--- I certainly hope someone can come up with a better solution! Kind regards, Roel Janssen