How to pass arguments to Cmd?

For example I might call `echo` with argument "hello", how can I do it? Assume cmd = `eho` , I found that push!(cmd.exec, "hello" does the trick, but exec is not documented, is this recommended?

Also, run from Base has the signature run(command, args...; wait::Bool = true). args is not documented, what does it mean? I tried Strings and Cmds but they do not work.

If you have a literal argument, just do

run(`echo hello`)

If you have it in a variable you would typically interpolate the string into the command

s = "hello"
run(`echo $s`)

There are also options like

run(Cmd(["echo", "hello"]))
5 Likes

Thanks, the situation is that I have optional trailing arguments, which can not be added with interpolation:

s = ""
`cmake -S src $s` # => `cmake -B src ''` instead of `cmake -S src`

Just interpolate an array (which can be empty) of your trailing arguments (if any):

julia> args = [];

julia> `cmake -S src $args`
`cmake -S src`

julia> args = ["foo", "bar baz"];

julia> `cmake -S src $args`
`cmake -S src foo 'bar baz'`

You have to to realize that, under the hood, a Cmd object is not constucting a single string to execute with a shell. It is constructing an executable name and a list of arguments that are passed to that executable directly in its low-level argument list. So, if s = "" and you interpolate $s, you are asking Julia to pass a literal empty string as an argument. (This is a good thing! Passing arguments directly means that you don’t have to worry about unexpected effects from spaces or metacharacters in the string.)

8 Likes

You can also splice commands into each other and it works they way you’d want, which is by treating Cmd objects like funny arrays of words. Example:

cmd = `ls -l`
if color
    cmd = `$cmd --color=yes`
end
5 Likes

Thanks! Such a shame that only after your reply did I realize the manual had already mentioned this situation.

I do know that commands are an array of strings, but it is surprising to find out that Julia did it the right way!

1 Like