0

I am trying to write an install script in babaska for my other babaska script (for some fun homogeneity).

Export doesn't seem to work using:

(shell "export NAME=" value)

Is there a canonical way to set environmental variables in Clojure / Babashka?

Jack Gee
  • 136
  • 6

2 Answers2

1

export is shell built-in; you can not call it outside a shell. So what you want to do instead is run your command with another environment. This can be done in sh with the :env option. E.g.

(-> (shell/sh "sh" "-c" "echo $X" :env {"X" "Hello"}) :out)

edit: global state for environment

At least on the JVM, there is no easy way to change the environment. So you are better off, writing your own function to do the calls and merge with your own global environment.

This example uses an atom to keep the environment around:

(def sh-env (atom {}))

(defn export!
  [m]
  (swap! sh-env merge m))

(defn sh
  ([cmd]
   (sh cmd {}))
  ([cmd env]
   (apply shell/sh (concat cmd [:env (merge @sh-env env)]))))

;;;

(def echo ["sh" "-c" "echo $X"])

(prn (sh echo))

(export! {"X" "Hello"})

(prn (sh echo))

(prn (sh echo {"X" "Goodbye"}))

(export! {"X" "Goodbye"})

(prn (sh echo))

; {:exit 0, :out "\n", :err ""}
; {:exit 0, :out "Hello\n", :err ""}
; {:exit 0, :out "Goodbye\n", :err ""}
; {:exit 0, :out "Goodbye\n", :err ""}
cfrick
  • 35,203
  • 6
  • 56
  • 68
  • I need to set the env variable permanently in the install. Is there a way to do this using your answer? – Jack Gee Oct 23 '22 at 20:54
  • Not on the JVM (yeah, there are ways, but they are hacky). You are better off writing your own function doing the calls. Then have some global state like an atom or a dynamic binding, if that fits your usecase better, around, where you keep those env vars and pass them down or merge them with per function-call arguments. – cfrick Oct 24 '22 at 05:49
1

They way to set environment variables with shell is like this:

(shell {:extra-env {"NAME" "FOOBAR"}} command)

See docs here.

Michiel Borkent
  • 34,228
  • 15
  • 86
  • 149
  • Anyway you could implement this in an install script? Save the variable names somewhere that can reused or something? I'd LOVE to stay babashka only for a project but if not I'll write a shell script to incorporate what's needed. – Jack Gee Oct 28 '22 at 10:30
  • You could of course define the option to shell in a variable :) – Michiel Borkent Oct 29 '22 at 12:19