This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-23
Channels
- # announcements (1)
- # babashka (68)
- # babashka-sci-dev (12)
- # beginners (36)
- # biff (22)
- # calva (20)
- # clerk (1)
- # clj-on-windows (7)
- # clojure (27)
- # clojure-conj (8)
- # clojure-denmark (2)
- # clojure-europe (133)
- # clojure-france (1)
- # clojure-italy (4)
- # clojure-nl (1)
- # clojure-uk (2)
- # clojurescript (7)
- # conjure (8)
- # core-async (111)
- # cursive (3)
- # datahike (4)
- # datalevin (18)
- # events (9)
- # gratitude (4)
- # guix (2)
- # helix (3)
- # hyperfiddle (62)
- # introduce-yourself (2)
- # kaocha (4)
- # london-clojurians (3)
- # lsp (7)
- # malli (34)
- # membrane (1)
- # nbb (9)
- # polylith (4)
- # portal (6)
- # reagent (4)
- # releases (2)
- # remote-jobs (4)
- # shadow-cljs (30)
- # sql (2)
- # tools-deps (58)
- # xtdb (9)
I have something working in bash which I'm trying to babashka. Amongst other things, the bash script calls the aws cli like this:
queryId=$(aws logs start-query .... --query-string "$my_query")
where my_query
is defined like this:
my_query=$(cat <<-END
fields @timestamp
| filter foo=bar
END
)
If I just do something like
(def my-query "fields @timestamp
| filter foo=bar")
(sh (format "aws logs start-query --query-string %s" my-query))
then every token of the query is interpreted as its own argument.
I could probably hand-escape the query, and put quotes here and there, but I'm wondering if there's something similar to whatever magic bash does, to have the query be one argument?you have the " " around $my_query
in the bash code. that makes it a single arg
try (format "aws logs start-query --query-string '%s'" my-query)
Ah, (format "... --query-string \"%s\"" my-query)
seems to do it. I have single-quotes in the "real" query.
Thanks @U7ERLH6JX 🙏
another way to deal with this which is possibly safer is to use a vec: (sh ["aws" "logs" ... my-query])
Yes! The vector works, no escaping needed!
And it also makes the command easier to read, as I can spare the format
, and do line breaks as I please 🙂
been bitten by these things way to often that i almost always use a vec here. youre also making life easier for the shell parser on the other side 😛
it is a fun little code we dont run when sending vecs: https://github.com/babashka/process/blob/master/src/babashka/process.cljc#L15-L62
it was doing it as expected i think. the bash code shouldve been equally confused
its varargs
Btw I knew that Paulus would jump into the convo at some point when it was related to bash and escaping 😄
(sh foo bar baz)
Only the first arg is split on spaces
yeah the usecase for the vector is when programmatically building the cmd. something i do often
Be free, skip the vec!
First arg can optionally be a map with extra goodies
Btw can you call process/tokenize on the formatted string you had earlier? It should work and if not I’d like to have a bug report. Be sure to upgrade to the newest bb before trying
I'll try that @U04V15CAJ and report back here
Unless the query contains single quotes. In that case you need to wrap the query in escaped double quotes. It should work like in bash.
I think this is a bug:
(prn
(babashka.process/tokenize "bb -e \"(require '[clojure.set])\""))
["bb" "-e" "(require [clojure.set])\""]
It loses the single quote in the escaped string, which shouldn't happenHm, upgraded bb to latest, tried
(sh (format "aws logs ... --query-string \"%s\"" "query-with-single-quotes 'foo'"))
and it worked out of the boxOh, nice! I have no idea how to see what version I upgraded from in Arch Linux, but it does sound like it's related.
Looks like I was also hitting an old version:
user=> (require '[babashka.process :as p])
nil
user=> (p/tokenize "bb -e \"(require '[clojure.set])\"")
["bb" "-e" "(require '[clojure.set])"]
ah yes, I'm on an old laptop and this fixed it:
==> Upgrading borkdude/brew/babashka
1.1.172 -> 1.1.173
I quite surely did have something that was relatively old. It printed the last expr to std-out, which I remember changed a while ago.
well we dont really believe in major versions do we? 😛
rather major versions = expect upheaval
since python is brought up, the changes that are considered breaking there is almost equal to a bb rewrite. everything else is non-breaking
Read one character from the console at a time. Works in unix-like terminals.
(require '[babashka.process])
(babashka.process/shell "stty -icanon -echo" )
(println "Echo is off; press `q` to quit.")
(loop []
(let [k (.read System/in)]
(println (char k))
(when (not= k 113)
(recur))))
(babashka.process/shell "stty icanon echo")
Thanks @elliot for helping figuring this out :)This was easier back in the MSDOS days. You'd just call getch()
... in Borland C
Maybe there is a cross platform way to shell out to a program which reads one character
Bash isn't usually available on windows but bash -c 'read -n1'
yeah, the bash case would be covered by the above, but Windows is the remaining problem
I think rebel readline accomplishes it using jLine. Bruce says it's the only way to do cross platform terminal manipulation
well, not the only way, since lanterna does it too, but one of the few things that seem to work in JVM world :)
I noticed the "single character" thing in lanterna relies on the above trick, but in Windows it relies on native hack stuff
Co-incidentally, I notice that on babashka.http-client you've added a PUT within the past couple of days. Can I take advantage of this now, or do I need to wait until a new release of babashka?
@U11EL3P9U You can add the http dependncy and use require
+ :reload
How do I check whether I'm in Babashka or in Clojure/JVM?