Can't quote a Cmd with equals sign correctly

I’ve been happily using DrWatson for my latest project, using its convention for filenames. For example, if my simulation uses parameters Dict(:a=>2, :b=>7), my output data file might be named simulation_a=2_b=7.h5.

But now the problem comes when I need to call a shell command from julia with one of these files. For example, I might want to run a shell command that is equivalently given by any of the following three options:

h5ls "simulation_a=2_b=7.h5"
h5ls 'simulation_a=2_b=7.h5'
h5ls simulation_a\=2_b\=7.h5

Either the filename itself should be surrounded by exactly one set of single or double quotes or each = should be escaped — not both quotes and escapes, and not two kinds of quoting.

The problem is when I try to make a Cmd to do these things; julia appears to be too clever for me, giving me either no quoting and no escaping, or quoting and escaping. These are some of the options I’ve tried (all of which fail):

julia> `h5ls simulation_a\=2_b\=7.h5`
`h5ls simulation_a=2_b=7.h5`

julia> `h5ls 'simulation_a=2_b=7.h5'`
`h5ls simulation_a=2_b=7.h5`

julia> `h5ls "simulation_a=2_b=7.h5"`
`h5ls simulation_a=2_b=7.h5`

julia> `h5ls "simulation_a\=2_b\=7.h5"`
`h5ls 'simulation_a\=2_b\=7.h5'`

julia> `h5ls "simulation_a\\=2_b\\=7.h5"`
`h5ls 'simulation_a\=2_b\=7.h5'`

julia> `h5ls simulation_a\\=2_b\\=7.h5`
`h5ls 'simulation_a\=2_b\=7.h5'`

julia> Cmd(["h5ls", "simulation_a=2_b=7.h5"])
`h5ls simulation_a=2_b=7.h5`

julia> Cmd(["h5ls", "'simulation_a=2_b=7.h5'"])
`h5ls "'simulation_a=2_b=7.h5'"`

julia> Cmd(["h5ls", "simulation_a\\=2_b\\=7.h5"])
`h5ls 'simulation_a\=2_b\=7.h5'`

Is there any way to achieve my goal?

(To make matters worse, I actually want to pass an array of files to a shell command…)

run(Cmd(["h5ls", "simulation_a=2_b=7.h5"]))

Personally, I avoid tricky characters, such as =, in filenames.

3 Likes

That gives me h5ls simulation_a=2_b=7.h5, which is not what I need.

You don’t want a shell command, you want a system command. You don’t need to do shell quoting if there is no shell.

julia> `h5ls simulation_a=2_b=7.h5` |> dump
Cmd
  exec: Array{String}((2,))
    1: String "h5ls"
    2: String "simulation_a=2_b=7.h5"
  ignorestatus: Bool false
  flags: UInt32 0x00000000
  env: Nothing nothing
  dir: String ""
2 Likes

Sorry. I misunderstood one of the error messages I was getting:

IOError: could not spawn `h5ls simulation_a=2_b=7.h5`: no such file or directory (ENOENT)

The “file or directory” it’s talking about is not the file I was talking about; it’s the h5ls command. I happened to test these things only with binaries that are in my own PATH, but not whatever run is using.

So yes, this works just fine. Thanks for your help.

Hello,

Same issue here, but with an additional quirk. The command I want to run is:

ffmpeg -f dshow -i video="HP HD Camera" -f rtsp rtsp://127.0.0.1:8554/live

The double quotes are needed, as for the equal sign without space.

When I type directly the command, I get:

julia> cmd = `ffmpeg -f dshow -i video="HP HD Camera" -f rtsp rtsp://127.0.0.1:8554/live`
`ffmpeg -f dshow -i 'video=HP HD Camera' -f rtsp rtsp://127.0.0.1:8554/live`

Escaping the double quotes is not better:

julia > cmd = `ffmpeg -f dshow -i video=\"HP HD Camera\" -f rtsp rtsp://127.0.0.1:8554/live`
`ffmpeg -f dshow -i 'video="HP' HD 'Camera"' -f rtsp rtsp://127.0.0.1:8554/live`

Any ideas?

PS

PS: I’m aware of FFMPEG.jl, but I need to keep the pipe open, so I went with a lower-lever approach. Suggestions are welcome.
PPS: Edits are for formatting & typos

The first thing you tried was actually correct, x="y z", "x=y z" and 'x=y z' are all the same to a shell.

AFAIK command strings use the same quoting syntax as any POSIX shell so if it works in sh/bash/zsh then the same command works in Julia.