Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Shell Command and Output

111 views
Skip to first unread message

kiwi

unread,
Dec 12, 2021, 6:42:18 PM12/12/21
to chez-scheme
I'm not yet able to get an output from chez for a shell command to read the current window title.  On racket I could do this:

> (define win (with-output-to-string (lambda() (system "xdotool getwindowfocus getwindowname"))))

and although system returns an output and an exit code 0 win will be the windows name.  In Chez the windows name is displayed and win will be ""

So question 1.  Is there a way to get the window name with the system command?

--

I have searched for ideas and studied the manual.  It seems that open-process-ports is the right command and I get:

> (open-process-ports "xdotool getwindowfocus getwindowname")
#<binary output port pid 8149 stdin>
#<binary input port pid 8149 stdout>
#<binary input port pid 8149 stderr>
8149

So I tried this to read the output and get the error message shown

> (define s (make-string 1000 #\nul))
> (substring s 0 (block-read <binary input port pid 8149 stdout> s 1000))
Exception: variable stdout> is not bound

input-port-ready? shows the same error message so clearly I'm misunderstanding something.

So, question 2.  What am I doing wrong and, thus, what would the correct code be?

Thanks

Jamie Taylor

unread,
Dec 12, 2021, 7:48:31 PM12/12/21
to kiwi, chez-scheme
As the documentation for system says, The subprocess may communicate with the user through the same console input and console output files used by the Scheme process.  So, it's output is not returned to the Scheme process, but sent straight on to the console.

You can find an example of using open-process-ports here

      (let-values ([(to-stdin from-stdout from-stderr pid)
                    (open-process-ports
                      (format "~a -b ./testfile.boot -q" (patch-exec-path *scheme*))
                      (buffer-mode block)
                      (native-transcoder))])
        (close-output-port to-stdin)
        (let ([out (get-string-all from-stdout)]
              [err (get-string-all from-stderr)])
          (close-input-port from-stdout)
          (close-input-port from-stderr)
          (unless (eof-object? err) (error 'bootfile-test1 err))
          out)))

(Note that this may be insufficient if the program produces a lot of output to either stdout or stderr, since the OS will only buffer so much before the process blocks.)

--
You received this message because you are subscribed to the Google Groups "chez-scheme" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chez-scheme...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/chez-scheme/c314100a-a8fa-41a0-b3ee-df393377781dn%40googlegroups.com.

kiwi

unread,
Dec 13, 2021, 12:48:30 AM12/13/21
to chez-scheme
Thanks Jamie,

Once I figured out how to deal with the output format I was able to create a simple demonstration that it worked.


    (let-values ([(to-stdin from-stdout from-stderr pid)
                (open-process-ports "xdotool getwindowfocus getwindowname")])
      (define tx (make-transcoder (utf-8-codec) (eol-style none)
                (error-handling-mode raise)))
      (printf "~s" (bytevector->string (get-bytevector-all from-stdout) tx)))
Reply all
Reply to author
Forward
0 new messages