From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: post@thomasdanckaert.be Newsgroups: gmane.lisp.guile.user Subject: Re: Shell commands with output to string Date: Tue, 22 Feb 2022 11:43:13 +0100 Message-ID: <6d1232e036287a4cc7994d9fac5fceec@thomasdanckaert.be> References: <1280eba0-81c0-6e7b-d512-bbd1f83a409c@posteo.de> <87tucryzdg.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="16958"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Zelphir Kaltstahl , guile-user@gnu.org To: alex.sassmannshausen@gmail.com Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Tue Feb 22 11:49:45 2022 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 1nMSjn-0004CZ-E9 for guile-user@m.gmane-mx.org; Tue, 22 Feb 2022 11:49:43 +0100 Original-Received: from localhost ([::1]:50810 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nMSjm-0005kR-AD for guile-user@m.gmane-mx.org; Tue, 22 Feb 2022 05:49:42 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:59160) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMSiZ-0005j0-Db for guile-user@gnu.org; Tue, 22 Feb 2022 05:48:27 -0500 Original-Received: from mail-108-mta139.mxroute.com ([136.175.108.139]:43873) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nMSiW-000196-Mj for guile-user@gnu.org; Tue, 22 Feb 2022 05:48:26 -0500 Original-Received: from filter006.mxroute.com ([140.82.40.27] 140.82.40.27.vultr.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta139.mxroute.com (ZoneMTA) with ESMTPSA id 17f21073aae0005a20.002 for (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256); Tue, 22 Feb 2022 10:43:16 +0000 X-Zone-Loop: 77b5d7b35b77e7388bd1a78233a2095b802293e059cc X-Originating-IP: [140.82.40.27] DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thomasdanckaert.be; s=x; h=Content-Transfer-Encoding:Content-Type: Message-ID:References:In-Reply-To:Subject:Cc:To:From:Date:MIME-Version:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=VOgOARQ/TXhdoseKkHnFh3+UkrDZ0KFhbfpAB4uciEA=; b=klNur/+hX+9VBIkNx2hJfP4baM VOC2Uplxy7pV2rMeNBoI8wRN2dS+m0YGlI3vHw8YeflUYDHxDaWbRWl2cQn/Nug4X/qsPp6EK/3FS YFNDCacizVHF7VPxQ2iKjnCBzbSj/0HdhR/pFqcwNCUDyueUBEpBYCzL7S1lOkRmRMycDRmlVr/c0 SJgUn9C7+bCTeXRiVf6SzHkg1XrIyNORidxCT4swO3nN4VMFxskEWU5d1Az4ilGBYhJlLj0Cc3mcy iSpvA4qt6bxko62q0eaNMpcr+iQyVrn8+FzGgS4cBrCcrsd4A2k+JxaNVPzdjG892triOLxdIOdkf b5iqg67w==; In-Reply-To: <87tucryzdg.fsf@gmail.com> X-Sender: post@thomasdanckaert.be X-AuthUser: post@thomasdanckaert.be Received-SPF: pass client-ip=136.175.108.139; envelope-from=post@thomasdanckaert.be; helo=mail-108-mta139.mxroute.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.29 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:18119 Archived-At: Hi, to throw in an example: I once used a function like the one below to handle stdout and stderr from external commands (from https://github.com/tdanckaert/jobview/blob/master/jobtools.scm#L38 ). Probably far from perfect (my first and only scheme project...), but hopefully it gives you an idea. (define (process-output proc cmd) "Runs CMD as an external process, with an input port from which the process' stdout may be read, and runs the procedure PROC that takes this input port as a single argument. Throws an exception 'cmd-failed if CMD's exit status is non-zero." (let* ((err-pipe (pipe)) (err-write (cdr err-pipe)) (err-read (car err-pipe)) (stderr (current-error-port))) (with-error-to-port err-write (lambda () (let* ((port (open-input-pipe cmd)) (ignore (setvbuf port 'block)) (result (catch #t ;; Catch any exception thrown by applying PROC to ;; the output of CMD: if CMD fails, we check the ;; exit status below; if CMD succeeds, PROC must be ;; able to deal with its output. (lambda () (proc port)) (lambda (key . args) (format stderr "Caught exception ~a from ~y~%" key proc)))) (status (close-pipe port))) (close-port err-write) (or (zero? status) (throw 'cmd-failed cmd status (get-string-all err-read))) result))))) Thomas On 2022-02-22 11:20, Alex Sassmannshausen wrote: > Hi Zelphir, > > I think you want to be using the popen / pipe procedures for this. See > https://www.gnu.org/software/guile/docs/docs-2.2/guile-ref/Pipes.html > for the chapter in the manual. > > Hope this helps :) > > Alex > > Zelphir Kaltstahl writes: > >> Corrections below. >> >> On 2/22/22 10:29, Zelphir Kaltstahl wrote: >>> Hello Guile users! >>> >>> How would I run a shell command from inside Guile and get its output >>> as a string, instead of the output being outputted directly? (Guile >>> 3.0.8) >>> >>> So far I have found >>> >>> ~~~~ >>> (system ...) >>> ~~~~ >>> >>> which I tried to use with >>> >>> ~~~~ >>> scheme@(guile-user)> (with-output-to-string >>>   (system "ls -al")) >>> >>> ;; lots of output immediately shown and not stored in variable >>> >>> ice-9/boot-9.scm:1685:16: In procedure raise-exception: >>> Wrong type to apply: 0 >>> >>> Entering a new prompt.  Type `,bt' for a backtrace or `,q' to >>> continue. >>> scheme@(guile-user) [1]> ,bt >>> In ice-9/ports.scm: >>>     476:4  2 (with-output-to-string 0) >>> While executing meta-command: >>> In procedure frame-local-ref: Argument 2 out of range: 1 >>> ~~~~ >>> >>> But this does not give me a string back. >>> >>> I also tried with >>> >>> ~~~~ >>> scheme@(guile-user)> (call-with-values (lambda () (system "ls -al")) >>> ... (lambda (exit-code output) output)) >>> >>> ;; lots of output immediately shown >>> >>> ice-9/boot-9.scm:1685:16: In procedure raise-exception: >>> Wrong number of values returned to continuation (expected 2) >>> >>> Entering a new prompt.  Type `,bt' for a backtrace or `,q' to >>> continue. >>> >>> scheme@(guile-user) [1]> ,bt >>> In current input: >>>     10:29  1 (_) >>> In ice-9/boot-9.scm: >>>   1685:16  0 (raise-exception _ #:continuable? _) >>> ~~~~ >>> >>> Is there another function I should be using? >>> >>> I would like to have the exit code and the output of a command. >>> >>> Best regards, >>> Zelphir >> >> Of course I should use `with-output-to-string` correctly: >> >> ~~~~ >> scheme@(guile-user)> (with-output-to-string >> (lambda () (system "ls -al"))) >> ;; directly outputted stuff >> $1 = "" >> ~~~~ >> >> But still not a win. >> >> Regards, >> Zelphir