How to input path in run() and joinpath() on Windows

Hello, everybody!

Today I have got in trouble with run() for putting the path from a string variable.

It seems ok with …

julia> test = joinpath("~")

julia> run(`dir $test`)
3D\ Objects
Application\ Data
\354\213\234\354\236\221\ \353\251\224\353\211\264
Process(`dir '~'`, ProcessExited(0))

But it returns errors even though the “Desktop” directory exists.

julia> test = joinpath("~", "Desktop")

julia> run(`dir $test`)
dir: cannot access '~Desktop': No such file or directory
ERROR: failed process: Process(`dir '~\Desktop'`, ProcessExited(2)) [2]

 [1] pipeline_error at .\process.jl:813 [inlined]
 [2] #run#536(::Bool, ::typeof(run), ::Cmd) at .\process.jl:728
 [3] run(::Cmd) at .\process.jl:726
 [4] top-level scope at REPL[20]:1


In addition, this also returns an error:

julia> run(`dir "~/tmp/"`)  binary       deprecated  external            papers  test
README.rst  codecov.yml  docs        initCobraToolbox.m  src     tutorials
Process(`dir '~/tmp/'`, ProcessExited(0))

julia> run(`mkdir "~/tmp/t"`)
mkdir: cannot create directory '~/tmp/t': No such file or directory
ERROR: failed process: Process(`mkdir '~/tmp/t'`, ProcessExited(1)) [1]

 [1] pipeline_error at .\process.jl:813 [inlined]
 [2] #run#536(::Bool, ::typeof(run), ::Cmd) at .\process.jl:728
 [3] run(::Cmd) at .\process.jl:726
 [4] top-level scope at REPL[30]:1


Certainly, mkdir works well in cmd on windows.

does this help?

overall, I think run would actually run the string you provide to it; otoh if you look at, for example, how mkdir works:

you will see that it calls different clib on windows. (that’s how Julia makes File works cross-platform so you don’t have to write ugly code yourself, by manipulating / \ strings etc.)

So in your case, ~ is simply ‘not a thing’ on Windows.

1 Like

When working with paths, it is generally easier to use the functions in Base.FileSystem for these kinds of things, i.e. use homedir() for ~ along with readdir() and mkdir().
This makes it easier to run code across platforms.

Also, for the mkdir example, try:

julia> run(`mkdir "~\\tmp"`)

It should make a folder named ~/tmp starting from the current working directory. Probably not the intended effect.
EDIT: So the mkdir example worked on one computer, but it failed on a different computer (both Win10). That’s probably because one computer had some build tools installed which over-ride some of the default windows commands (mkdir example worked on this one).

Thanks for reply, @jling and @zaki!. Actually, I want to run git with a path as an input parameter.

What I want to revise is:

In that file,

installDir = "~/tmp/cobratoolbox"
run(`git clone --depth=1 --recurse-submodules $installDir`);

result in creation of “~” folder in pwd instead of seeking %userprofile%.

However, look at the following code:

PALM(modelDir, "$(joinpath(dirname(pathof(COBRA)), "../test/scriptFile.m"))"; nMatlab=nWorkers, outputFile="modelCharacteristics.mat", varsCharact=varsCharact, cobraToolboxDir=installDir)

This function gets the same parameter installDir, but this function does interpret “~” as %userprofile% on windows.

In that function, the following code is executed:

  if !isdir(cobraToolboxDir)
        cmd = "git clone $cobraToolboxDir"
        @info cmd
        run(`sh -c $cmd`)

In conclusion, I am still not sure when the julia interpret tilde as %userprofile%.
However, I think I can manage to this problem based on the above suggestions.

I think Julia is just passing the tilde without interpreting it.
The git and sh -c commands are interpreting it.
Though on my system, neither version interprets ~ as home directory—both of them create a ~/tmp folder starting from pwd.

EDIT: Tried it on the second computer, and the sh -c version works properly there (again an issue with different build tools). The specific sh command is bundled with git, and it interprets ~ as the home directory. This can be verified by running where sh and sh -c "~" in cmd.