如何将 JVM 属性 line.separator 设置为从 bash 换行
how to set JVM property line.separator to newline from bash
我想将 JVM 系统 属性 line.separator
设置为 Windows 上的单个换行符(默认情况下,其他地方已经是单个换行符)。
这个scala脚本用来显示有效line.separator 属性:
#!/usr/bin/env scala
val bytes = sys.props("line.separator").map { _.toInt }.mkString(" ")
printf("line.separator bytes: %s\n",bytes)
在 windows JVM 上,它通常打印以下内容:
line.separator bytes: 13 10
简而言之,我正在寻找一种方法来启动我的测试脚本,以便打印以下输出:
line.separator bytes: 10
我可以通过以下 JAVA_OPTS 设置实现此目的:
export JAVA_OPTS=-Dline.separator=$'\n'
但前提是我还通过用双引号将 $JAVA_OPTS 括起来来修改标准 Scala 脚本。这是接近 scala 脚本末尾的部分(即,没有进行必要的修改):
execCommand \
"${JAVACMD:=java}" \
$JAVA_OPTS \
"${java_args[@]}" \
"${classpath_args[@]}" \
-Dscala.home="$SCALA_HOME" \
$OVERRIDE_USEJAVACP \
$WINDOWS_OPT \
scala.tools.nsc.MainGenericRunner "$@"
通过这两个修改,上面的测试脚本打印如下:
$ reportLineSeparator.sc
line.separator bytes: 10
但是,向 JAVA_OPTS 添加引号不是一个可行的选择,因为这会阻止它被取消设置或指定多个设置。
所以要求似乎是以某种方式安排正确处理未引用的 JAVA_OPTS 而不会丢失编码的换行符。
我开始怀疑是否有解决方案,尽管我希望有人能证明我是错的。
更新:似乎如果使用 bash 数组而不是 JAVA_OPTS,这将提供一个解决方案,因为它可以在 scala 脚本中引用。换句话说,将上面未加引号的 $JAVA_OPTS 替换为:
"${JAVA_OPTS_ARR[@]}" \
令我惊喜的是,当 JAVA_OPTS_ARR 未定义时它也不会引起问题。
但是,这不是一个可行的解决方案,因为无法导出 bash 数组(参见 Exporting an array in bash script)
追问:进一步思考这个问题后,我得出结论,插值不是问题所在。需要引号将变量包含为单个命令行参数。因此,这引发了一个问题,即是否可以使用内部字段分隔符 (IFS) 将整个 line.separator 定义保留为不带引号的单个命令行参数。
好吧,看来如果我在 scala 启动脚本中添加以下内容,line.separator 设置似乎会生效:
IFS=' '
然后我可以像这样附加到 JAVA_OPTS 并获得所需的行为:
JAVA_OPTS="$JAVA_OPTS "-Dline.separator=$'\n'
IFS 设置必须先于未加引号的 $JAVA_OPTS 出现。
更新:@som-snytt 建议的这个调用似乎有效:
scala -J-Dline.separator=$'\n' -nc lineSeparatorBytes.sc
JAVA_OPTS
是一个古老的约定,但不是标准。它于 2007 年引入 scala
脚本,并在 2010 年被 -J
取代。
我认为最好的选择(可以这么说)是 scala -J-Dline.separator=$'\r'$'\n'
。
你的建议现在有一个 PR,这看起来很安全,除了它还保留了案例:
JAVA_OPTS="-Xmx256m <tab> -Xss1m"
.
Shell 引用太有趣了!我试着每五年左右刷新一次我伤痕累累的记忆。
编辑:答案是将 line.separator 传递给 Scala 的后台编译服务器失败了。编译服务器有几个问题(可以用 fsc
为 "fast" scala 编译器调用),现在已弃用。一如既往,此处的解决方案是使用 -nc
为您的脚本请求 "no compile daemon"。编译脚本需要多花一秒钟,但可以节省数小时或数天的调试时间。
我想将 JVM 系统 属性 line.separator
设置为 Windows 上的单个换行符(默认情况下,其他地方已经是单个换行符)。
这个scala脚本用来显示有效line.separator 属性:
#!/usr/bin/env scala
val bytes = sys.props("line.separator").map { _.toInt }.mkString(" ")
printf("line.separator bytes: %s\n",bytes)
在 windows JVM 上,它通常打印以下内容:
line.separator bytes: 13 10
简而言之,我正在寻找一种方法来启动我的测试脚本,以便打印以下输出:
line.separator bytes: 10
我可以通过以下 JAVA_OPTS 设置实现此目的:
export JAVA_OPTS=-Dline.separator=$'\n'
但前提是我还通过用双引号将 $JAVA_OPTS 括起来来修改标准 Scala 脚本。这是接近 scala 脚本末尾的部分(即,没有进行必要的修改):
execCommand \
"${JAVACMD:=java}" \
$JAVA_OPTS \
"${java_args[@]}" \
"${classpath_args[@]}" \
-Dscala.home="$SCALA_HOME" \
$OVERRIDE_USEJAVACP \
$WINDOWS_OPT \
scala.tools.nsc.MainGenericRunner "$@"
通过这两个修改,上面的测试脚本打印如下:
$ reportLineSeparator.sc
line.separator bytes: 10
但是,向 JAVA_OPTS 添加引号不是一个可行的选择,因为这会阻止它被取消设置或指定多个设置。
所以要求似乎是以某种方式安排正确处理未引用的 JAVA_OPTS 而不会丢失编码的换行符。
我开始怀疑是否有解决方案,尽管我希望有人能证明我是错的。
更新:似乎如果使用 bash 数组而不是 JAVA_OPTS,这将提供一个解决方案,因为它可以在 scala 脚本中引用。换句话说,将上面未加引号的 $JAVA_OPTS 替换为:
"${JAVA_OPTS_ARR[@]}" \
令我惊喜的是,当 JAVA_OPTS_ARR 未定义时它也不会引起问题。
但是,这不是一个可行的解决方案,因为无法导出 bash 数组(参见 Exporting an array in bash script)
追问:进一步思考这个问题后,我得出结论,插值不是问题所在。需要引号将变量包含为单个命令行参数。因此,这引发了一个问题,即是否可以使用内部字段分隔符 (IFS) 将整个 line.separator 定义保留为不带引号的单个命令行参数。
好吧,看来如果我在 scala 启动脚本中添加以下内容,line.separator 设置似乎会生效:
IFS=' '
然后我可以像这样附加到 JAVA_OPTS 并获得所需的行为:
JAVA_OPTS="$JAVA_OPTS "-Dline.separator=$'\n'
IFS 设置必须先于未加引号的 $JAVA_OPTS 出现。
更新:@som-snytt 建议的这个调用似乎有效:
scala -J-Dline.separator=$'\n' -nc lineSeparatorBytes.sc
JAVA_OPTS
是一个古老的约定,但不是标准。它于 2007 年引入 scala
脚本,并在 2010 年被 -J
取代。
我认为最好的选择(可以这么说)是 scala -J-Dline.separator=$'\r'$'\n'
。
你的建议现在有一个 PR,这看起来很安全,除了它还保留了案例:
JAVA_OPTS="-Xmx256m <tab> -Xss1m"
.
Shell 引用太有趣了!我试着每五年左右刷新一次我伤痕累累的记忆。
编辑:答案是将 line.separator 传递给 Scala 的后台编译服务器失败了。编译服务器有几个问题(可以用 fsc
为 "fast" scala 编译器调用),现在已弃用。一如既往,此处的解决方案是使用 -nc
为您的脚本请求 "no compile daemon"。编译脚本需要多花一秒钟,但可以节省数小时或数天的调试时间。