Julia run external programm with environmental variables: Don't interpolate $ - julia

I'm trying to run a shell command from Julia which needs to have an environment variable set to some specific value. I have two problems:
How to set environment variables to be used by Julia's
run(command, args...; wait::Bool = true) command?
How to pass special sign $ to this process without interpolating it? I want to test if the variable is available for my program.
What I have done so far:
Let's say I want to define an environment variable FOO=bar and check if it's accessible within the shell with shell command echo $FOO.
To prevent Julia interpolating $ I already quoted it like explained in the official documentation but then echo is printing $PATH and not its value.
So for FOO I got the following output
julia> run(`echo '$FOO'`)
$FOO
Process(`echo '$FOO'`, ProcessExited(0))
but would have expected something like
julia> run(`echo '$FOO'`)
Process(`echo '$FOO'`, ProcessExited(0))
if FOO is undefined or
julia> run(`echo '$FOO'`)
bar
Process(`echo '$FOO'`, ProcessExited(0))
if the value is set to bar.

Check out the Julia documentation on environment variables. You can set an environment variable with:
julia> ENV["FOO"] = "bar"
"bar"
and you can retrieve the value of an environment variable with:
julia> ENV["FOO"]
"bar"
julia> ENV["PATH"]
"really long string of my path"
As you've already stated, you can avoid interpreting the $ by single-quoting that part of your run command. I'm not totally sure what you are looking for there.

Not elegant, but this works:
julia> write("temp.sh", "echo foo=\$BAR");
julia> run(`bash temp.sh`)
foo=
Process(`bash temp.sh`, ProcessExited(0))
julia> ENV["BAR"] = "bar";
julia> run(`bash temp.sh`)
foo=bar
Process(`bash temp.sh`, ProcessExited(0))
I guess Julia injects the content of ENV into the shell before running the command. And that's all I needed to know as I'll be launching other executables which require some environment variables to be set. So when setting them inside ENV[], they will be available to the executables you run from within that Julia session.

Related

How do I run multiple scripts within a Julia script?

I'm new to programming in Julia and I'm currently making a grid search script that can cycle through different parameters for two other Julia scripts. I then want to save the output together with the input variables in a file, what I don't know however is how to run a script with predefined parameters within a script. The two scripts work when executed via the command line.
Thanks in advance.
Ok, I'm not sure weather i understand the whole question, but...
Input parameters are stored in ARGS, you can change them, and hence run script with this parameters as input:
julia> ARGS
0-element Array{String,1}
julia> push!(ARGS, "Parameter 1")
1-element Array{String,1}:
"Parameter 1"
julia> include("test.jl")
p = "Parameter 1"
#where test.jl is:
for p in ARGS
#show p
end
But don't do your program in such way, just construct a function, put them into the module and later use them in one script. See doc for more information about it.

What is JuliaLang's equivalent to Python's sys.executable?

I would like to retrieve the path of the currently running Julia interpreter from Julia. In Python, this can be achieved with sys.executable.
Base.julia_cmd() is probably what you need. It returns the full command line that was used to invoke the current julia process, with the default options spelled out. Base.julia_exename() returns the name of the executable.
julia> Base.julia_cmd()
/Users/aviks/dev/julia/julia5/usr/bin/julia -Cnative -J/usr/lib/julia/sys.dylib --compile=yes --depwarn=yes
julia> Base.julia_exename()
"julia"
If you just want the location of the julia executable, try one of these:
julia> julia_bin_exe = joinpath(Base.Sys.BINDIR,Base.julia_exename())
"/home/mkitti/src/julia/usr/bin/julia"
julia> Base.julia_cmd()
`/home/mkitti/src/julia/usr/bin/julia -Cnative -J/home/mkitti/src/julia/usr/lib/julia/sys.so -g1`
julia> typeof(Base.julia_cmd())
Cmd
julia> Base.julia_cmd()[1]
"/home/mkitti/src/julia/usr/bin/julia"
julia> julia_bin_exe == Base.julia_cmd()[1]
true

How to alias quit() to quit?

This is just a convenience but I think useful. Note that IPython allows a pure quit as does Matlab. Thus it would be reasonble in Julia to allow aliasing.
Thanks for any ideas as to how to do this.
Quitting in Julia
If you are using Julia from the command line then ctrl-d works. But if your intention is to quit by typing a command this is not possible exactly the way you want it because typing quit in the REPL already has a meaning which is return the value associated with quit, which is the function quit.
julia> quit
quit (generic function with 1 method)
julia> typeof(quit)
Function
Also Python
But that's not rare, for example Python has similar behavior.
>>> quit
Use quit() or Ctrl-D (i.e. EOF) to exit
Using a macro
Using \q might be nice in the Julia REPL like in postgres REPL, but unfortunately \ also already has a meaning. However, if you were seeking a simple way to do this, how about a macro
julia> macro q() quit() end
julia> #q
Causes Julia to Quit
If you place the macro definition in a .juliarc.jl file, it will be available every time you run the interpreter.
As waTeim notes, when you type quit into the REPL, it simply shows the function itself… and there's no way to change this behavior. You cannot execute a function without calling it, and there are a limited number of ways to call functions in Julia's syntax.
What you can do, however, is change how the Functions are displayed. This is extremely hacky and is not guaranteed to work, but if you want this behavior badly enough, here's what you can do: hack this behavior into the display method.
julia> function Base.writemime(io::IO, ::MIME"text/plain", f::Function)
f == quit && quit()
if isgeneric(f)
n = length(f.env)
m = n==1 ? "method" : "methods"
print(io, "$(f.env.name) (generic function with $n $m)")
else
show(io, f)
end
end
Warning: Method definition writemime(IO,MIME{symbol("text/plain")},Function) in module Base at replutil.jl:5 overwritten in module Main at none:2.
writemime (generic function with 34 methods)
julia> print # other functions still display normally
print (generic function with 22 methods)
julia> quit # but when quit is displayed, it actually quits!
$
Unfortunately there's no type more specific than ::Function, so you must completely overwrite the writemime(::IO,::MIME"text/plain",::Function) definition, copying its implementation.
Also note that this is pretty unexpected and somewhat dangerous. Some library may actually end up trying to display the function quit… causing you to lose your work from that session.
Related to Quitting in Julia
I was searching for something simple. This question hasn't been updated since 2017, as I try to learn Julia now, and spend some time googling for something simple and similar to python. Here, what I found:
You can use:
exit()
Note
I use julia 1.53

Get a list of current variables in Julia Lang

I am new to Julia Lang. I am coming from the background of Matlab.
In Matlab, when pressing whos command I will get all variables in the current scope; and also, I can store them in another variable like x=whos; Is there such commands exists in Julia?
Example code in Matlab:
>> a=3;
>> b=4;
>> whos
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
a 1x1 8 double
b 1x1 8 double
prefix 1x16 16 char
Total is 18 elements using 32 bytes.
An Update:
whos()
... is not working either in iJulia or at the command prompt in Julia-1.0.0.
It is working in Julia-0.6.4, though.
On the other hand,
varinfo()
....prints information about the exported global variables in a module. For Example,
julia-1.0> varinfo()
name size summary
–––––––––––––––– ––––––––––– –––––––––––––––––––––––––––––––
Base Module
Core Module
InteractiveUtils 154.271 KiB Module
Main Module
PyPlot 781.872 KiB Module
ans 50.323 KiB Plots.Plot{Plots.PyPlotBackend}
myrepl 0 bytes typeof(myrepl)
x 88 bytes 1×6 Array{Int64,2}
y 0 bytes typeof(y)
Hope, this is found useful.
You can use Julia's whos functions just like that Matlab command.
julia> whos()
Base Module
Core Module
Main Module
ans Nothing
julia> x = 5
5
julia> whos()
Base Module
Core Module
Main Module
ans Int64
x Int64
Any modules (packages/libraries) you import into your local scope (using using) will also show up in the list (as Modules, like Base, Core, and Main above).
Additionally, you can ask about names exported by Modules. Base is the module containing the standard library.
julia> whos(Base)
! Function
!= Function
!== Function
$ Function
% Function
& Function
* Function
+ Function
.... (lots and lots more)
Considering that that result scrolls way off my screen, you can understand why you'd want to filter the results. For that you can use Regexes. (For more info on Julia's regexes, see this manual section)
julia> whos(r"M")
Main Module
julia> whos(Base, r"Match"i)
DimensionMismatch DataType
RegexMatch DataType
each_match Function
eachmatch Function
ismatch Function
match Function
matchall Function
I wasn't aware of the whos function before you asked, so thanks for helping me learn something new too. :)
Julia issue #3393 on github is about adding memory sizes to the whos output. It also references making whos return a value rather than just printing the information out.
Not sure if there is something better, but
names(Main)[4:end]
seems to work. The [4:end] part is because it includes :Main, :Core and :Base which I think you would not want. I hope they will always be at the beginning.
whos() is not available in newer versions of Julia (1.0 onward). Use varinfo() instead. For example, varinfo(Core,r".*field.*")
As of version 1.1 there is also the #locals macro
The experimental macro Base.#locals returns a dictionary of current local variable names and values
Release notes

Setting environment variable in ZSH gives number expected

I'm trying to set an array in ZSH (configured using oh-my-zsh).
export AR=(localhost:1919 localhost:1918)
but I'm getting an error like such:
zsh: number expected
If I don't add the export command, it's just fine. I'm not typing the above in a *rc file, just in the zsh prompt. What could be the problem?
You can't export an array in zsh.
For more info: http://zsh.sourceforge.net/Guide/zshguide02.html
Note that you can't export arrays. If you export a parameter, then
assign an array to it, nothing will appear in the environment; you can
use the external command printenv VARNAME (again no $ because the
command needs to know the name, not the value) to check. There's a
more subtle problem with arrays, too. The export builtin is just a
special case of the builtin typeset, which defines a variable without
marking it for export to the environment. You might think you could do
typeset array=(this doesn\'t work)
but you can't --- the special
array syntax is only understood when the assignment does not follow a
command, not in normal arguments like the case here, so you have to
put the array assignment on the next line. This is a very easy mistake
to make. More uses of typeset will be described in chapter 3; they
include creating local parameters in functions, and defining special
attributes (of which the export attribute is just one) for
parameters.

Resources