I want to set JVM System property line.separator
to a single newline on Windows (it's already a single newline by default everywhere else).
This scala script is used to display the effective line.separator property:
#!/usr/bin/env scala
val bytes = sys.props("line.separator").map { _.toInt }.mkString(" ")
printf("line.separator bytes: %s\n",bytes)
On a windows JVM, it normally prints the following:
line.separator bytes: 13 10
Briefly, I'm looking for a way to launch my test script so that it prints the following output:
line.separator bytes: 10
I can achive this with the following JAVA_OPTS setting:
export JAVA_OPTS=-Dline.separator=$'\n'
but only if I also modify the standard scala script by surrounding $JAVA_OPTS with double quotes. Here's the section near the end of the scala script verbatim (i.e., WITHOUT the needed modification):
execCommand \
"${JAVACMD:=java}" \
$JAVA_OPTS \
"${java_args[@]}" \
"${classpath_args[@]}" \
-Dscala.home="$SCALA_HOME" \
$OVERRIDE_USEJAVACP \
$WINDOWS_OPT \
scala.tools.nsc.MainGenericRunner "$@"
With these two modifications, the test script above prints the following:
$ reportLineSeparator.sc
line.separator bytes: 10
Adding quotes to JAVA_OPTS is not a viable option, however, since that would prevent it from being unset, or from specifying multiple settings.
So the requirement seems to be to somehow arrange for the unquoted JAVA_OPTS to be correctly handled without losing the encoded newline.
I'm starting to suspect that there is solution, although I'm hopeful that someone will prove me wrong.
Update: it seems that if a bash array is used instead of JAVA_OPTS, that would provide a solution, since it could be quoted in the scala script. In other words, replace the unquoted $JAVA_OPTS above with this:
"${JAVA_OPTS_ARR[@]}" \
I was pleasantly surprised that it also doesn't cause problems when JAVA_OPTS_ARR is undefined.
However, this isn't a viable solution because it's not possible to export bash arrays (see Exporting an array in bash script)
Follow-up: after further thinking about this problem, I concluded that interpolation isn't the issue. The quotes are needed to contain the variable as a single command line argument. So that raises the question as to whether the Internal Field Separator (IFS) could be used to keep the entire line.separator definition as a single command line argument without quotes.
Okay, it seems that if I add the following to the scala launch script, the line.separator setting seems to take effect:
IFS=' '
I can then append to JAVA_OPTS like this and get the desired behavior:
JAVA_OPTS="$JAVA_OPTS "-Dline.separator=$'\n'
The IFS setting has to occur prior to where the unquoted $JAVA_OPTS occurs.
Update: this invocation, suggested by @som-snytt seems to work:
scala -J-Dline.separator=$'\n' -nc lineSeparatorBytes.sc