Environment Variables in interactive window

In my .zshrc startup script I set some environment variables export FOO="BAR" which I’d like to use in Julia.

From a terminal I get

julia> ENV["FOO"]
"BAR"

But from a VS code interactive session using shift+enter

# foo.jl
ENV["FOO"]

Gives
ERROR: KeyError: key "FOO" not found so it seems that the interactive session doesn’t execute the .zshrc. Previously this didn’t seem to be an issue, I’ve only noticed this since updating to MacOS 13.0, but I cannot confirm the update is related.

VS Code executes julia directly, it doesn’t launch your shell to then execute julia from there.

I don’t know if it’s respected in VS Code, but you could put ENVs in your startup.jl` file (which can be disabled when you run Julia):

ENV["FOO"] = "something"

I don’t know about macOS, maybe something changed:

1 Like

I had a feeling this was the case. It must have been coincidence that I haven’t noticed this previously.

This would mean I’d be defining environment variables in two distinct places, which I’d rather avoid. Perhaps it’s the only practical option though.

MacOS has been using zsh as default since 2019, I’m not sure why that article makes it look like a 13.0 change.

1 Like

Maybe you used to launch VS Code from your shell? Then the environment will propagate.

1 Like

Yes, I was thinking could you run your .zshrc from Julia? You CAN… but it would clear out the ENVs when the process exits, as specified. I don’t know if there’s a workaround for that, I tried to google it, but gave up, though I was helpful already.

1 Like

I presumed this would be possible. Or storing all environment variables in a .json file which both .zshrc and startup.jl can load in.

1 Like

Perhaps direnv might interest you, which can be used by both your shell, and also in VS Code. I wrote a blog post about direnv + Julia here: Project specific Julia configuration with direnv | Fredrik Ekre.

Or simply such a file:

MYENV1=something
MYENV2=other

A start for something working in Julia (though I’m not sure why it fails):

julia> @eval "ENV[\"" * join(split("MYENV1=something", "="), "\"]=\"")
"ENV[\"MYENV1\"]=something"

Or you could use evalfile for legal Julia code, and something like above, in reverse, for the shell.

Thanks this

Thanks I’ve installed this as project level environment variables seems helpful.

If I went down this approach I’d prefer an established file format, as this seems to involve having to reinvent the wheel a little bit

You can use DotEnv.jl or ConfigEnv.jl which parses standard env files.

1 Like

Well, I was thinking, that’s just standard shell/bash (and I guess .zshrc) code. I was aiming for as simple as possible, for you, at least on the shell side, and see it was just “standard env files”. I’ve never parsed JSON in a shell, it wasn’t invented (nor web browsers) when I started using shells… I’m sure it’s possible, just seemed like a heavier dependency (on both sides). Plain text files are as standard as they come (in Unix/LInux, and I guess by now in macOS), JSON (or e.g. XML) only needed for hierarchical, and extensibility which you don’t need there.

You wouldn’t even have to parse it on the shell side:

. FILE # POSIX compliant

Actually I forget export, and it should still be trivial to parse (and exclude that) on the Julia side:

export VARNAME="my value"      # shorter, less portable version

@fredrikekre I see export isn’t used by DotEnv.jl files, and I think needed in shells, for sub-shells (or some workaround to not need that?).

1 Like