Interpolating multiple parameters into a Cmd

Thank you Steven.
Raising this topic from the dead.

In my scenario, concatenation of the command fails, as I get single apostrophes in the command that I don’t want, see my first comment.

Any ideas how I can avoid this?
Hardcoding the parameters (second run command) is a workaround (but obviously I loose much flexibility)

infile = raw"C:\temp\t\in.flac"
outfile = raw"C:\temp\t\out.mp3"

    @assert splitext(infile)[2] == ".flac"
    parms = "-ar 48000 -ab 320k -y -ac 2 -vn -map_metadata 0 -id3v2_version 3"
    cmd = `ffmpeg -i $infile $parms $outfile`
    #THIS FAILS, because there are single quotes in the parameters, how can I get rid of them?  
    `ffmpeg -i 'C:\temp\t\in.flac' '-ar 48000 -ab 320k -y -ac 2 -vn -map_metadata 0 -id3v2_version 3' 'C:\temp\t\out me mo.mp3'`

    cmd = `ffmpeg -i $infile -ar 48000 -ab 320k -y -ac 2 -vn -map_metadata 0 -id3v2_version 3 $outfile`
    #run(cmd) #works but prints to stdout
    rs = run(pipeline(cmd, stdout=devnull, stderr=devnull))
    @assert rs.exitcode == 0
    @assert rs.termsignal == 0

I split this into a new topic, which is better than attaching to an ancient thread.

Your mistake here is that $parms, where parms is a String, tries to interpolate parms as a single argument, not as a list of multiple arguments. Doing this robustly is one of the reasons why Cmd is nice and shelling out sucks — Julia’s Cmd doesn’t run into trouble even if parms contains spaces, quotes, or other shell metacharacters.

However, in your case, you want multiple arguments, i.e. you want the spaces in parms to be treated as metacharacters. (You’re maybe thinking of this as launching a shell, which it isn’t.) In that case, the right thing is simply to make parms an array of arguments:

parms = ["-ar", "48000", "-ab", "320k", "-y", "-ac", "2", "-vn", "-map_metadata", "0", "-id3v2_version"]
cmd = `ffmpeg -i $infile $parms $outfile`

or equivalently

parms = split("-ar 48000 -ab 320k -y -ac 2 -vn -map_metadata 0 -id3v2_version 3", ' ')
cmd = `ffmpeg -i $infile $parms $outfile`
1 Like

or equivalently

parms = `-ar 48000 -ab 320k -y -ac 2 -vn -map_metadata 0 -id3v2_version 3`
cmd = `ffmpeg -i $infile $parms $outfile`