как установить свойство JVM line.separator для перевода строки из bash - PullRequest
0 голосов
/ 16 ноября 2018

Я хочу установить системное свойство 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'

но только если я также изменю стандартный скрипт scala, заключив $ JAVA_OPTS в двойные кавычки. Вот раздел ближе к концу дословного сценария 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 без потери закодированного перевода строки.

Я начинаю подозревать, что есть решение, хотя я надеюсь, что кто-то докажет, что я неправ.

Обновление: кажется, что если вместо JAVA_OPTS используется массив bash, это обеспечит решение, поскольку его можно заключить в скрипт scala. Другими словами, замените без кавычек $ JAVA_OPTS выше на это:

"${JAVA_OPTS_ARR[@]}" \

Я был приятно удивлен, что это также не вызывает проблем, когда JAVA_OPTS_ARR не определен.

Однако это нереалистичное решение, поскольку невозможно экспортировать массивы bash (см. Экспорт массива в сценарии bash )

Продолжение: после дальнейшего размышления над этой проблемой я пришел к выводу, что интерполяция не является проблемой. Кавычки необходимы, чтобы содержать переменную в качестве единственного аргумента командной строки. Таким образом, возникает вопрос о том, можно ли использовать Внутренний разделитель полей (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

1 Ответ

0 голосов
/ 18 ноября 2018

JAVA_OPTS - это древнее соглашение, но не стандарт. Он был введен в сценарий scala в 2007 году и заменен на -J в 2010 году.

Я думаю, что лучший вариант (так сказать) - scala -J-Dline.separator=$'\r'$'\n'.

Для вашего предложения теперь есть PR, который кажется безопасным, за исключением того, что он также сохраняет вкладку для дела:

JAVA_OPTS="-Xmx256m <tab> -Xss1m".

Цитирование в оболочке - это так весело! Я стараюсь обновлять свою шрамовую память каждые пять лет или около того.

Редактировать: ответ состоял в том, что передача line.separator на фоновый сервер компиляции Scala прервалась. Есть несколько проблем с сервером компиляции (которые могут быть вызваны с помощью fsc для «быстрого» компилятора scala), который сейчас не рекомендуется. Решение здесь, как всегда, заключается в использовании -nc для запроса «no compile daemon» для вашего скрипта. Компиляция скрипта занимает секунду дольше, но вы экономите часы или дни отладки.

...