How to pipe data to other process via temporary file
Asked Answered
H

1

5

I want to sent some data from my program to a process executed via uiop:run-program.

The following works:

(require :asdf)
(asdf:load-system :uiop)
(uiop:with-temporary-file (:stream dot-program-stream
                           :pathname dot-program-file)
  (format dot-program-stream "digraph g { n1 -> n2; }")
  (finish-output dot-program-stream)
  :close-stream
  (uiop:with-temporary-file (:pathname png-data)
    (uiop:run-program '("/usr/bin/dot" "-Tpng") :input dot-program-file
                                                :output png-data)
    (uiop:launch-program '("/usr/bin/display") :input png-data)))

It seems rather convoluted.

A simpler version, where I used only a stream did not finish-output and did not use the :close-stream label resulted in dot producung an empty 0 byte file.

How to execute a process and pass it data generated by my lisp program as standard input?

Hightail answered 14/7, 2018 at 20:4 Comment(0)
C
6

Take a closer look at the documentation of uiop:launch-program and uiop:run-program, especially the options for the :input and :output keys.

You can call launch-program with :input :stream. Launch-program returns a process info object that contains the stream connected to that program's standard input behind the accessor process-info-input, so you can print to that.

If you have a different program that produces output that should go into that input stream, you have several options:

  • create a temporary file, then read it and print it to the second program's input stream (that seems to be your current approach)
  • use run-program with :output :string for the first call, then use launch-program with :input :stream for the second and write the output of the first to that stream
  • use launch-program also for the first call, in this case with :output :stream, then read from that output and print it to the second program's input

You can either read everything first, then write everything, or you can do buffered reading and writing, which might be interesting for long running processes.

Instead of this in-process buffering, you could also use a fifo (named pipe) from your OS.

Cambell answered 15/7, 2018 at 14:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.