I have two suggestions for Sys.which
, which was added in #26559:
Make it both accept and return Cmd
s rather than String
s.
Return nothing
when the given command is not found rather than throwing an error. (This was actually suggested by someone else in that PR.)
As a motivation for this change, consider the case of selecting an executable from a list of candidates. With the above suggestions, one could write this
tar = coalesce(Sys.which(`tar`), Sys.which(`gtar`))
and use the value of the resulting variable directly in commands, pipeline
, etc. Currently this must be written as
tar = try
Sys.which("tar")
catch
try
Sys.which("gtar")
catch
error(":(")
end
end
which is significantly less ergonomic.
Definitely agree about returning nothing
if a command doesn鈥檛 exist. However, I think I disagree with the part about returning a Cmd
. It鈥檚 a path and the canonical representation of a path is a string; a Cmd
is a kind of "vector of words". We should make sure that nothing
throws an error when spliced into a Cmd
though (it may already).
If sys.which("tar")
returns a Cmd
for the program tar, how are the arguments then specified?
how are the arguments then specified?
Interpolation
run(`$(Sys.which("tar")) xzf thingo.tar.gz`)
It鈥檚 a path and the canonical representation of a path is a string; a Cmd is a kind of vector of words.
True, though in this case the path is a path to an executable, which is likely mostly useful in Cmd
s, I would think.
Oops, nothing does not throw an error when spliced into a command:
julia> `$nothing`
`nothing`
That should certainly be fixed since it is unlikely that running a command called nothing
is what is intended; it's a bit ad hoc but I think it's the right thing to do here.
True, though in this case the path is a path to an executable, which is likely mostly useful in Cmds, I would think.
The fact that it's a path to an executable is irrelevant. The key fact is that it's not a collection of words like a Cmd
is, it's always just one path. E.g. if there's a space in the path to the executable, you have to go to extra trouble to make sure it's not split there; with a string you get the right behavior without doing anything.
There seems to be broad agreement on what to do, so de-triaging. Whether this can make it into master before the release can be discussed in #27298.
Most helpful comment
The fact that it's a path to an executable is irrelevant. The key fact is that it's not a collection of words like a
Cmd
is, it's always just one path. E.g. if there's a space in the path to the executable, you have to go to extra trouble to make sure it's not split there; with a string you get the right behavior without doing anything.