Passing two strings to the external utility diff in Julia

Viewed 85

I've been trying to pass two strings to the diff command line utility for its graphical side-by-side comparison capabilities in Julia. My attempts thus far have included the following:

s1 = "<very long multiline string 1>"
s2 = "<very long multiline string 2>"

# Results in LoadError: parsing command `diff -y <(echo $(s1)) <(echo $(s2))`:
# special characters "#{}()[]<>|&*?~;" must be quoted in commands
attempt1 = read(`diff -y <(echo $(s1)\) <(echo $(s2))`, String)

# Results in diff: extra operand '<(echo'
attempt2 = read(`diff -y \<\(echo $(s1)\) \<\(echo $(s2)\)`, String)

# Results in diff: missing operand after '<(echo
attempt3 = read(`diff -y "<(echo $(s1)) <(echo $(s2))"`, String)

# Results in diff: missing operand after '<(echo $(s1)) <(echo $(s2))'
attempt4 = read(`diff -y '<(echo $(s1)) <(echo $(s2))'`, String)

# Results in diff: <(echo <very long multiline string 1>: Filename too long
attempt5 = read(`diff -y \<\("echo $(s1)"\) \<\("echo $(s2)"\)`, String)

and so forth. The strings s1 and s2 are generated during the execution of a script and are therefore not accessible as files. I'm trying to bypass that with the bash "pseudo-file" syntax

diff -y <(command 1) <(command 2) ,

but Julia does something to the command strings so that they don't operate as they do in bash. How might I pass two strings to diff in Julia, then?

1 Answers

Yes, Julia's Cmd is not the same as bash. If you are not on Windows, you can emulate bash behaviour with the FIFOStreams.jl package

using FIFOStreams
s1 = """
Humpty Dumpty sat on a wall,
Humpty Dumpty had a great fall.
All the king's horses and all the king's men
Couldn't put Humpty together again.
"""

s2 = """
Humpty Dumpty sat on a wall,
Humpty Dumpty had a great fall.
Four-score Men and Four-score more,
Could not make Humpty Dumpty where he was before.
"""

s = FIFOStreamCollection(2)
io = IOBuffer()

attach(s, pipeline(ignorestatus(`diff -y $(path(s, 1)) $(path(s, 2))`); stdout = io))

fs1, fs2 = s

print(fs1, s1)
print(fs2, s2)
close(s)

And the result

julia> println(String(take!(io)))
Humpty Dumpty sat on a wall,                                    Humpty Dumpty sat on a wall
,
Humpty Dumpty had a great fall.                                 Humpty Dumpty had a great f
all.
All the king's horses and all the king's men                  | Four-score Men and Four-sco
re more,
Couldn't put Humpty together again.                           | Could not make Humpty Dumpt
y where he was before.
Related