New babashka release: 0.4.5
Babashka proper:
- Add java.net.InetSocketAddress
- Add support for slingshot https://github.com/babashka/babashka/issues/675
- Add STM facilities (`dosync`, ref
, etc.)
- Fix .wait
, .notify
interop on arbitrary classes
Deps.clj (used for resolving deps and clojure
invocations):
- Fix JVM option parsing https://github.com/borkdude/deps.clj/issues/46
Sci: various minor performance improvements.
https://github.com/babashka/babashka/blob/master/CHANGELOG.md#045
I'm a real noob at bb, and at running "imperative" commands from clj at all. How would you structure a pretty simple script that is supposed to do about this thing, here in zsh loop:
for i in `seq 1 100`; do
echo $i >> main.go
git add .
git commit -m $i
;done
@emilaasa for
translates to doseq
in clojure (used for side effects. seq 1 100
is (range 1 100)
(not sure about inclusive/exclusive in bash).
The echo call can be done using (spit "main.go" i :append true)
Calling git can be done using shelling out e.g. with clojure.java.shell
or babashka.process
or in tasks using shell
Thanks I'll try with doseq, I did reach for that but I think I messed up 🙂
Just use println
when you're not sure, print things and you will figure it out
Ah great it works exactly the same with waiting for shell output and everything!
(doseq [i (range 100)]
(append-to-file "main.go" (gofunc (str "funfunc" i)))
(gofmt "main.go")
(add "main.go")
(commit "asdf"))
Thanks a lot - as normal with a good newbie question I feel stupid now 😄
no need, this channel is n00b question friendly!
These implicit (or explicit let's be honest) have tripped me up before
I am still unable to capture stderr in babashka/process:
(require '[babashka.process :as p :refer [process]]
'[<http://clojure.java.io|clojure.java.io> :as io])
(def c (process ["bash" "-c" "echo An error message > /dev/stderr"] {:err :inherit :shutdown p/destroy}))
(with-open [rdr (io/reader (:out c))]
(binding [*in* rdr]
(loop []
(let [line (read-line)]
(println :line line)
(when (not (nil? line))
(recur))))))
prints
An error message
:line nil
I was expecting
:line An error message
:line nil
Any hints?Can you reproduce? This happens in both the rebl and the cider repls.
What are you expecting this example to do?
You are reading from the process's stdout, not stderr right
But does not :inherit
merge the two?
No, :inherit
writes directly to the parent's corresponding stream
😳
The name is adopted from the Java API: https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#inheritIO()
This works:
(require '[babashka.process :as p :refer [process]]
'[<http://clojure.java.io|clojure.java.io> :as io])
(def c (process ["bash" "-c" "echo An error message > /dev/stderr"]
{:shutdown p/destroy}))
(with-open [rdr (io/reader (:err c))]
(binding [*in* rdr]
(loop []
(let [line (read-line)]
(println :line line)
(when (not (nil? line))
(recur))))))
Note: I did not set :err :inherit
and I read from :err
, not :out
I see. redirectErrorStream
is perhaps what I want: https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#inheritIO()
Ah I see
you could also do {:out *out* :err *out*}
or write to a custom stringwriter
But it might be nice to be able to distinguish stderr and stdout also. Is there a way to read both at the same time? Thanks for the help btw!
yes, just start two such loops
I will try. I'd imagine one would have to finish before the other begins, but I'll test it out.
well, you could run them side by side in a thread or so
That is what I did 🙂 (.start (Thread. my-loop))
. I'm used to multithreading stuff being such a pain in the behind. That seems to be one aspect of the language which is easier in Java than in Python
you can also do (future ..)