sellout/external-program

Input isn't passed to the external program

Closed this issue · 3 comments

(external-program:run "cat" nil :input *standard-input*)

You see, no matter how I hit enter, cat won't print anything.
Is it a bug? How to work it around?

Which CL implementation are you using?

First, you are not telling the output to go anywhere. It’s also possible that you are not actually typing your input into wherever *standard-input* is coming from. Try

(external-program:run "cat" nil
                      :input (make-string-input-stream "foo")
                      :output *standard-output*)

Hopefully that will work. If it does, then try

(external-program:run "cat" nil
                      :input *standard-input*
                      :output *standard-output*)

If that doesn’t work, then the problem is that wherever you are typing is not connected to *standard-input*.

You could also try unwrapping the call to see how the underlying CL implementation behaves. EG, on CCL it would be:

(ccl:run-program "cat" nil
                 :input (make-string-input-stream "foo")
                 :output *standard-output*
                 :wait t)

If that has the same behavior as external-program:run, then the problem is likely in how you are using the function (or, less likely, in the CL implementation).

Result: the 1st and the 3rd work, but the 2nd doesn't work. (I'm using SBCL)

(sb-ext:run-program "/usr/bin/cat" nil 
                    :input (make-string-input-stream "foo") 
                    :output *standard-output*)

prints "foo" as I expected.

(read-line *standard-input*)

reads one line as I expected.

but

(sb-ext:run-program "/usr/bin/cat" nil 
                    :input *standard-input* 
                    :output *standard-output* :wait t)

won't run.

sbcl \
  --eval '(require :external-program)' \
  --eval '(external-program:run "cat" nil :input (make-string-input-stream (format nil "foo~%")) :output *standard-output*)' \
  --quit

Prints foo and a newline for me, like it should.

echo foo | sbcl \
  --eval '(require :external-program)' \
  --eval '(external-program:run "cat" nil :input *standard-input* :output *standard-output*)' \
  --quit

Also prints foo and a newline for me, like it should.

I think there is no bug here.