I am using Julia to combine information from a combination of sources and generate a (rather lengthy) string that is a call to an external program. I can generate a String containing the text that I would type into the shell but I can’t work out how to turn that into a Cmd to call with run. I currently get around that by writing the string to a file named cmd.sh and calling
If you need to run it in the shell then run(`sh -c $cmd`) is best (where cmd is a String variable)
If you just need to pass multiple arguments, then call just run(cmd), where cmd is built up from interpolating other Cmd objects and arrays of Strings.
Unfortunately the first version doesn’t work because the contents of $cmd are enclosed in double quotes. To the shell, it looks like one long file name.
It seems that I will need to stay with the current approach or try to use your second approach and right now I think writing to a file then executing that as a shell script is easier.
I appreciate that appropriately quoting strings that are parts of commands is important but not having a way to override the quoting is awkward.
The right way to do this is to avoid the shell completely. e.g. suppose you have an array filenames of filenames strings and an array options with the option strings. You would construct the command to run by, for example:
Note that in the options variable, there is no need for additional quoting. You write "--b=option b", not"--b=\"option b\"". The reason is that these options are passed directly to myprog, without going through the shell.
Avoiding the whole issue of quoting and escapes is a huge benefit of circumventing the shell, along with the performance advantage of not launching the shell process.
Is there a simple way to run a command from a string and get the output as a string ? Something like
cmd = "ls *"
out = readstring(`$cmd`)
but that works. I managed to get something working by copying and modifying Base.repl_cmd but it’s quite ugly and complicated. And I don’t want to do any interpolation, just run the string and get the output.
To read the output of an an external program as a string, simply do e.g.:
read(`ls`, String)
If by “command” you mean “shell command”, e.g. "ls *" is a shell command if you want * to be interpreted as a glob metacharacter, then you need to run it with a shell, e.g.:
shellcmd = "ls *"
read(`sh -c $shellcmd`, String)
By default, commands don’t use the shell because shelling out sucks — they just directly launch executables. Note also that there are portable, native Julia equivalents for anything you might want to do via a shell, e.g. globbing via Glob.jl or ls via readdir.
PS. Sorry, didn’t mean to necro-post. This came up in my discourse feed because of @Bittu_Kumar’s post above and I didn’t notice that I was responding to one of the ancient posts!