Is there any way to run an external command with * in it?

Hello

I am trying to run an external command "rsync * a: " with run() and the * makes it impossible. there is an old unresolved question on this. How to quote special characters in run() function

I am now making a detour to R to make it happen
R"
system(“rsync * a:”)
"
but that seems very inelegant.

Is there a way to do this natively in Julia?

best regards, Jack

You can use the Glob.jl package:

run(`rsync $(glob("*")) a:`)
3 Likes

Thanks fredrikekre!

That worked brilliantly! And I would never have thought of that usage of glob.

best, Jack

The problem is not quoting or “special characters”. You can do run(`rsync "*" a:"`) which passes the * to rsync just fine. However, it looks like you don’t actually want to pass * to rsync — you want * expansion (globbing), but this is performed by the shell and Julia’s run does not invoke the shell — it runs rsync directly.

If you want to run rsync via a shell, you can do so by directly invoking sh -c, i.e.:

run(`sh -c "rsync * a:"`)

(Invoking a shell is what R’s system function is doing.)

However, invoking the shell is a suboptimal approach in general. Not only is it slower (first the system launches a sh process, then sh launches rsync), but it also runs into lots of brittle issues with quoting. (And there are portability problems, e.g. on Windows.)

That’s why we generally recommend pure-Julia alternatives to shell features, like the Glob.jl package if you want to do glob expansion of paths, or Julia’s pipeline function if you want to pipe.

8 Likes

Thanks stevengj

That makes perfect sense to me. I am indeed globbing and it works as it should with Glob.jl.

all the best, Jack

1 Like