How would something like
diff <(echo aoeu) <(echo snth)
"diff <(echo aoeu) <(echo snth)".!
import scala.sys.process._ def diff(one: String, two: String): String = Seq( "bash", "-c", """ diff <(printf '%s\n' "$1") \ <(printf '%s\n' "$2"); retval=$? (( retval == 1 )) || exit "$retval" """, "_", one, two).!!
This can be tested in practice:
scala> diff("hello", "world") res1: String = "1c1 < hello --- > world "
To break down the reasoning:
world; in yours,
snth) to be passed out-of-band from code. This is critical to avoiding injection attacks when such content is parameterized.
bashas your executable ensures that process substitution syntax is available.
diffreturns an exit status indicating that the two inputs are not identical as an error, while ensuring that other errors still become exceptions in scala.
printf '%s\n' "$1"instead of
echo "$1"avoids ambiguities in the POSIX definition of
echo(see in particular the APPLICATION USAGE section).
_fills in the
Note that invoking a sequence rather than a string also prevents you from needing a shell at all in many cases:
Seq("hello", "world").! doesn't need to invoke any shell, but can be implemented so as to directly starts an executable named
"hello world".! is equivalent to
Seq("sh", "-c", "hello world").!, with an extra executable invocation with both performance cost and potential security vulnerabilities required for implementation. See Shellshock for an example of a (now-near-universally-patched) case where a shell invocation with no explicit user-controlled parameters could still be vulnerable in practice (when invoked from a web server following CGI conventions for exporting request parameters as environment variables); avoiding unnecessary shells is thus preferable behavior where feasible.