1

My attempt:

(import 'java.lang.Runtime)
(. (Runtime/getRuntime) exec (into-array ["youtube-dl" "--no-playlist" "some youtube video link"]))

I also tried sh. But both approaches don't do what I want - running a program similarly like shell does (sh waits until program exits, exec launches it and doesn't wait for its exit; both don't output anything to standard output). I want live showing of process output, e.g. when I run youtube-dl I want to see progress of a video download.

How to do this simple simple task in Clojure?

monnef
  • 3,903
  • 5
  • 30
  • 50

1 Answers1

2

You must start the process and listen to its output stream. One solution is :

(:require [clojure.java.shell :as sh]
          [clojure.java.io :as io])

(let [cmd ["yes" "1"]
      proc (.exec (Runtime/getRuntime) (into-array cmd))]
      (with-open [rdr (io/reader (.getInputStream proc))]
        (doseq [line (line-seq rdr)]
          (println line))))
Minh Tuan Nguyen
  • 1,026
  • 8
  • 13
  • It's not exactly same as shell does it (e.g. shell allows to "rewrite" current line, so for example progress bar is always shown only once), but it's close enough. Thank you :). – monnef Aug 27 '17 at 05:17
  • In my example I just use the println function. For the rewrite behaviour you must implement your own println function that prints the carriage return. See: https://stackoverflow.com/questions/9566654/print-a-carriage-return-in-java-on-windows-on-console – Minh Tuan Nguyen Aug 27 '17 at 08:08