https://kotlinlang.org logo
Title
r

Rob Elliot

01/02/2022, 11:42 AM
Any recommendations for a library that can do string escaping, other than
org.apache.commons.text.StringEscapeUtils
?
j

Joffrey

01/02/2022, 11:54 AM
String escaping for what? Usually it comes with whatever you want to escape it for. For instance HTTP libraries likely have URL-encoding functions, markdown libraries for markdown escaping etc
r

Rob Elliot

01/02/2022, 12:04 PM
Shell. I want to take a bunch of strings representing an executable and its arguments, of the form you would pass to
java.lang.ProcessBuilder(String... command)
, and print them in a form that could be passed to
sh -c
and would work. Single quotes around each string would mean replacing any single quotes in the string with
'\''
- that might be all that's needed
e

ephemient

01/02/2022, 12:27 PM
the
List<String>/vararg String
methods of
ProcessBuilder
pass arguments to the executable directly, without going through shell, which avoids the need for escaping. why do you need something to pass to
sh -c
?
j

Joffrey

01/02/2022, 12:31 PM
@ephemient some commands are actually shell built-ins, which might be the reason why
sh -c
is needed
@Rob Elliot I hope you don't have to support windows'
cmd
, otherwise good luck with quoting
e

ephemient

01/02/2022, 12:32 PM
yeah there is no reliable quoting method on Windows since every program gets to interpret the command line in their own way…
r

Rob Elliot

01/02/2022, 12:33 PM
For
toString
purposes, really - I want to represent it in a way that is easy for me to read & copy into an actual shell if I want to play with it.
Not interested in supporting Windows
e

ephemient

01/02/2022, 12:34 PM
@Joffrey there are very few shell builtins I'd expect to be called by non-shell users - the only one I can think of is
time
which exists as a separate executable on many systems anyway
r

Rob Elliot

01/02/2022, 12:35 PM
This is naive, I presume I will shortly find a test that breaks it. Also there must be more efficient ways that multiple contains.
private fun String.escape() = if (contains(' ') || contains('\'')) {
  "'${replace("'", "'\\''")}'"
} else this
e

ephemient

01/02/2022, 12:38 PM
anything involving `#$&();<>?[\]`{|}~` is liable to be interpreted by the shell, and other whitespace characters such as
\t
are usually in
$IFS
too
also
!^
may special meaning depending on the shell
r

Rob Elliot

01/02/2022, 1:28 PM
Thanks, that's very helpful
e

ephemient

01/02/2022, 1:42 PM
if you want to see how Bash generates quoted representations of strings and have Bash 4.0+ (notably, not macos),
ProcessBuilder("/bin/bash", "-c", "echo \"\${@@Q}\"", "-s", "<\$hello>", "world!\n").start().inputReader().readLine()
// returns '<$hello>' $'world!\n'
but note that the
$''
syntax is Bash-specific
lots of shell-specific stuff is pretty shell-specific