shell – how to change CWD for a command executed in Julia? – Code Utility

[

Julia doesn’t use shell like other languages for running external programs. How can I do the equivalent of cd temp_dir && some_cmd in Julia? As far as I understand cd() changes the working directory globally which is a problem if I execute blocks of code in parallel.

,

An option which is safe for use with concurrent tasks is setenv(cmd, dir=some_working_dir). This will create a Cmd object which will get some_working_directory in the child process without interfering with the working directory in your Julia session.

For example,

julia> run(setenv(`ls`, dir="temp_dir"))
code.jl  file.txt
Process(setenv(`ls`; dir="temp_dir"), ProcessExited(0))

,

Looking at the docstring for the cd function:

help?> cd
search: cd Cdouble gcd gcdx secd vecdot asecd cld Cmd codeunit CodeInfo

  cd(dir::AbstractString=homedir())

  Set the current working directory.

  cd(f::Function, dir::AbstractString=homedir())

  Temporarily changes the current working directory and applies function f
  before returning.

We can use the second method to cd into a directory, run a command, and then continue execution.

julia> cd(readdir, "temp_dir/")
2-element Array{String,1}:
 "code.jl" 
 "file.txt"

julia> cd("temp_dir/") do
           mkdir("subdir")
       end

julia> cd(readdir, "temp_dir/")
3-element Array{String,1}:
 "code.jl" 
 "file.txt"
 "subdir"  

We can pass any function as the first argument, including custom ones (concisely written using a do block).

,

I figured out a way which makes the shell user happy.

Just write

run(`bash -c """cd temp_dir && some_cmd"""`)

and we are good!

Bonus of this method is that these sub-shells are independent. E.g., I want an external program to generate force field for me, as in a molecular dynamics simulation. I need generate a tone of point-wise data. I would write it in parallel (using Threads). The cd function in Julia will somehow change the working directory for all threads while in the solution given above it is thread-safe.

]