How can I pass environment variables to shell process? I want to execute this command from planck AWS_PROFILE=foo aws s3 ls
. But when I try this way (planck.shell/sh "aws" "s3" "ls" :env {"AWS_PROFILE" "foo"})
I got an error "launch path not accessible"
. Thanks!
@tothda I think this means that aws
is not on the path.
In other words, I think it would fail without the :env
No, without the :env
it calls the aws
command
cljs.user=> (require 'planck.shell)
nil
cljs.user=> (planck.shell/sh "aws" "s3" "ls")
{:exit 255, :out "", :err "Unable to locate credentials. You can configure credentials by running \"aws configure\".\n"}
cljs.user=>
Hmm, I would try with-sh-env
As in
(shell/with-sh-env {"FOO" "bar"} (shell/sh "env"))
this also works
(shell/sh "env" :env {"FOO" "bar"})
What is up with the launch path error? Hrm.
@tothda As a sanity check, you could fire up a Clojure REPL and try the same command, but instead using [clojure.java.shell :as shell]
to see if it reveals more.
okay, I'll do thanks
If Planck's code sees exit codes of 126 and 127 it throws that exception. I can't recall exactly why, but the goal is to behave like clojure.java.shell
.
strange, but the it works with clojure.java.shell
Odd
https://www.dropbox.com/s/yqbftsef0utp1v9/Screenshot%202018-03-06%2014.15.55.png?dl=0
@tothda Well, one cool thing you can do, since Planck is self-hosted, is dynamically re-define the behavior.
If you do (in-ns 'planck.shell)
in a Planck REPL you can then
(defn- sh-internal
[& args]
(let [{:keys [cmd opts cb]} (s/conform ::sh-async-args args)]
(when (nil? cmd)
(throw (s/explain ::sh-async-args args)))
(when-not (s/valid? (s/nilable ::string-string-map?) *sh-env*)
(throw (js/Error. (s/explain-str ::string-string-map? *sh-env*))))
(let [{:keys [in in-enc out-enc env dir]}
(merge {:out-enc nil :in-enc nil :dir (and *sh-dir* [:sh-dir *sh-dir*]) :env *sh-env*}
(into {} (map (comp (juxt :key :val) second) opts)))
dir (and dir (:path (as-file (second dir))))
async? (not= cb nil-func)
translated (translate-result (js/PLANCK_SHELL_SH (clj->js cmd) in in-enc out-enc
(clj->js (seq env)) dir (if async? (assoc-cb cb))))
{:keys [exit err]} translated]
(if async? nil translated))))
This would get rid of the code that looks at the exit values and it will let you see the true :exit
and :err
when I do this the result is {:exit 127, :out "", :err ""}
And clojure.java.shell
can find aws
and returns an :exit 0
. Hrm.
I wonder if aws
is itself a script that has an interpreter that isn't found with the way Planck launches it.
aws
was installed with brew
and the shebang line is #!/usr/local/Cellar/awscli/1.11.170/libexec/bin/python
127
means it can't find the command http://tldp.org/LDP/abs/html/exitcodes.html
Cool. I'm doing brew install awscli
myself to see what's up
And this only occurs when you actually provide the credentials
yes, when I don't pass the AWS_PROFILE then aws
is found an it gives an error
Cool, I can repro the issue @tothda, will dig into it now and let you know shortly
Thanks a lot @mfikes!
@tothda Still, digging, but a (unsavory) workaround appears to be to set the environment prior to running Planck, as in
AWS_PROFILE=foo planck
@tothda Discovered that if you set any env, Planck blows away the needed PATH
environment variable. I'm looking into the Java source code to see what it actually does in that case that allows it to succeed. So two more workarounds result from this discovery:
1. Use "/usr/local/bin/aws"
as the first parameter to sh
2. If you specify an env map, include a "PATH"
key, with "/usr/local/bin"
and whatever else might be needed.
I'm going to fix the underlying Planck issue to make it behave like clojure.java.shell
I tried the 2nd workaround and it works indeed. Thx
@tothda Was able to fix it. That was a good catch. In summary, Planck needs to ensure that the environment passed is for the child process. It was messing with the parent process, and thus breaking the ability to even find things on the PATH
.
Fantastic! That was fast. Thanks again for you help and for Planck!
Cool @tothda my plan is to release Planck when ClojureScript 1.10.x comes out (perhaps in a week). If you need help building it prior to then, let me know.
Not needed, I'm okay with the adding the PATH to env until the new release is out.
Cool 🙂