External program with string argument interpolation

Hi,
I can’t figure how (after reading https://docs.julialang.org/en/v1/manual/running-external-programs/manual) to run a command with string arguments enclosed with “”

Le’s say the shell command I want to invoke is

shell> echo “toto”

then

julia> run(echo "toto")

actually corresponds to

shell> echo toto

without ""s
How can I preserve the ""s ?

P.S. I know that my example is not relevant. I am actually dealing with the following command:

gdb -batch -ex “disassemble/rs dexp” /tmp/libdexp_C.so

This?

julia> run(`echo \"toto\"`)
"toto"
Process(`echo '"toto"'`, ProcessExited(0))
1 Like

What happens if you do:

julia> cmd=`gdb -batch -ex "disassemble/rs dexp" /tmp/libdexp_C.so`

julia> run(cmd)

Because, as you can see:

julia> dump(cmd)
Cmd
  exec: Array{String}((5,))
    1: String "gdb"
    2: String "-batch"
    3: String "-ex"
    4: String "disassemble/rs dexp"
    5: String "/tmp/libdexp_C.so"
  ignorestatus: Bool false
  flags: UInt32 0x00000000
  env: Nothing nothing
  dir: String ""

ARGV[4] is the complete string not splitted by the space. So I expect it to work as you want to have it.

Noteworthy: run doesn’t run the command in a shell :Running External Programs · The Julia Language

The command is never run with a shell. Instead, Julia parses the command syntax directly, appropriately interpolating variables and splitting on words as the shell would, respecting shell quoting syntax. The command is run as julia 's immediate child process, using fork and exec calls.

2 Likes

Interpolation should be straight forward: Running External Programs · The Julia Language

2 Likes

Thank you very much !

It did not work because my symbol was not defined and I (wrongly) guessed that it was an interpolation issue…

Sorry for the noise and thank you for the dump(cmd) example : it helps a lot !

1 Like

Yes, instead of fiddling with quotes, I tend to rely on variable interpolation in such cases:

julia> complex_str = """foo    "bar" \t baz"""
"foo    \"bar\" \t baz"

julia> cmd = `echo $complex_str`
`echo 'foo    "bar" 	baz'`

julia> collect(cmd)
2-element Array{String,1}:
 "echo"
 "foo    \"bar\" \t baz"

julia> run(cmd)
foo    "bar" 	baz
Process(`echo 'foo    "bar" 	baz'`, ProcessExited(0))
1 Like

Just because it hasn’t been brought up yet: Enquoting the string argument in single quotes works similarly to other Posix shells, in that it escapes everything except ' itself and `, so in your example run(`echo '"toto"'`) should also just work.

The difference is, that with this the double quotes " are passed as part of the ARG value, which may be not wanted.
In the shell you want:
“a string with space” passed as single argument value, so you do e.g.:

bash > some_cmd -input "a string with space"

Now argv[2]=a string with space
(without the ")
In the case of

run(`some_cmd  -input '"a string with space"'`)

which is identical to

run(`some_cmd  -input \"a string with space\"`)

some_cmd now receives as argv[2]:
"a string with space"
Where double quotes are part of the string.

To clarify by example, in the shell this is what the question is about:

bash> echo "1 2 3" | egrep -e 1 2 3
grep: 2: No such file or directory
grep: 3: No such file or directory

ok, easy, just do:

bash> echo "1 2 3" | egrep -e "1 2 3"
1 2 3

Yeah, works.
Now Julia’s backticks would do:

bash>  echo "1 2 3" | egrep -e "\"1 2 3\""

or

bash>  echo "1 2 3" | egrep -e '"1 2 3"'

Result empty, of course, the douple quotes are not echoed, so no match by grep.