conch
conch copied to clipboard
Not possible to inherit process I/O
Hi!
I need to run a command from within clojure that does two things (one essential, one nice) that require the command to have inherited the process I/O.
- The first (nice) one is that it prints color when it detects that it is connected to a terminal.
- The second one is that it will prompt for my SSH passphrase if it needs it when connected to a terminal.
Here's the code that I'd love to replace with conch (but can't right now):
(defn ^:private realtime-output-sh
"A version of sh in which the child process inherits I/O."
[& args]
(let [command-line (take-while string? args)
{:keys [dir env]} (->> args
(drop-while string?)
(apply hash-map))
process-builder (let [pb (doto (ProcessBuilder. command-line)
(.inheritIO)
(.directory (io/file dir)))]
(.clear (.environment pb))
(doseq [[env-name env-value] env]
(.put (.environment pb) env-name env-value))
pb)
process (.start process-builder)
exit-code (.waitFor process)]
exit-code))
I'm not sure what the best way to do this would be. Perhaps allowing :inherit
as a value for :in
, :out
, and :err
?
This should definitely be supported by conch. I don't think an :inherit
value for everything is the way to go, since you can't only inherit stdin, for example. Probably just need to add an :inherit-io
option.
I think you're always handling every I/O channel now, right? I think it can be mapped out like so:
- If any channel has :inherit, call
.inheritIO
. (Or always call.inheritIO
?) - Override the channels afterward to be the same as they would have been, except for
:inherit
ones.
Whether this is a good idea is another question.
I think it might be, because it seems a lot easier to say "Or you can put :out :inherit
" than explaining how :inherit-io changes how the other options work.
That seems reasonable.
I'd take a PR to add this.