Как передать аргументы в процесс Java из сценария оболочки

Это может быть дубликат, но исходные вопросы, которые я нашел, не помогли решить проблему.

Еще одна перезапись вопроса.

У меня есть это приложение Java:

public static void main(final String[] args) { System.out.println("DEBUG: arguments passed to the main - " + Arrays.toString(args)); System.exit(new TaskRunner().run(args)); } 

Если я вызываю код напрямую с двумя аргументами:

$ nohup ${JAVA_HOME}/bin/java -cp /opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/* wib.runner.TaskRunner -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities" > /opt/sw/calypso/logs/taskrunner/log.direct.log 2>&1

он печатает

[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities]

что я и ожидаю. Но если я напишу этот сценарий оболочки ( startScheduledTask.sh ):

NOW_DATE=`date '+%Y%m%d%H%M%S'`

nohup ${JAVA_HOME}/bin/java -cp some:classpath:values package.name.classname "$@" > /opt/random/path/tplogs/classname/${aVariableLogName}.${NOW_DATE}.log 2>&1

и запустите его как

$ ./startScheduledTask.sh -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities" &

Я получаю этот вывод:

[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD, IPV, -, EOD, Rates, Input, -, Commodities, Volatilities]

(т. е. второй аргумент разбивается на девять аргументов, потому что он содержит восемь пробелов). Поэтому я считаю, что сценарий виноват.

Как это исправить?

One Solution collect form web for “Как передать аргументы в процесс Java из сценария оболочки”

Когда оболочка анализирует командную строку, она удаляет кавычки, но запоминает структуру текста, которую они подразумевают. (Это грубое упрощение, см. Bash (1) или Command Command Language для более подробной информации.) Например, ввод в командной строке

 -blah apple -secondfruit "green banana" -some more 

заставляет оболочку идентифицировать шесть слов или жетоны:

  1. -blah
  2. apple
  3. -secondfruit
  4. green banana
  5. -some
  6. more

которые будут сохранены в памяти как

 -blahⓧappleⓧ-secondfruitⓧgreen bananaⓧ-someⓧmoreⓧ 

где представляет нулевой байт. Иногда это будет отображаться или сообщаться как

 -blah apple -secondfruit green banana -some more 

так что вы можете поверить, что цитаты просто игнорируются, и у вас есть семь слов, а на самом деле у вас есть то, что вы хотите.

Заметка:

В приведенном выше представляет собой нулевой байт. То, что я описываю здесь, – это стандартная обработка аргумента-обработки аргументов. Если вы напечатаете

 ls -l fruit.sh "I came here for an argument" startScheduledTask.sh 

программа /bin/ls вызывается с помощью строки

 lsⓧ-lⓧfruit.shⓧI came here for an argumentⓧstartScheduledTask.shⓧ 

в памяти, и это интерпретируется как

  • argv [0] = ls
  • argv [1] = -l
  • argv [2] = fruit.sh
  • argv [3] = I came here for an argument
  • argv [4] = startScheduledTask.sh

Этот точно такой же процесс происходит, если вы

  1. ввод команды java непосредственно в вашу основную интерактивную оболочку,
  2. выполнение команды java которая находится в сценарии оболочки, или
  3. запуская сценарий оболочки, набрав команду, например ./startScheduledTask.sh прямо в вашу основную интерактивную оболочку,

так что это не проблема. Любая программа, которая не может обрабатывать свои аргументы, разделенные нулевыми символами, не может работать в Unix & Linux.

TL; DR

Ваша первая команда верна. "$@" дает вам то, что вы хотите; это правильный способ, чтобы скрипт оболочки передавал свои аргументы программе, которую он вызывает. Если вы добавите код отладки в свою программу для прокрутки своих аргументов, распечатывая каждый из них в новой строке и / или в скобках (но не все в одной строке, разделенные пробелами), вы увидите, что "$@" пропускает шесть аргументов в программу.


Хорошо, еще больше:

  • У вашего пути класса есть звездочки ( * s) в нем? В самом деле? Я немного из практики с Java, но это кажется странным для меня. Пожалуйста, дважды проверьте, что вы делаете это правильно для своей системы. Но если он корректно работает, когда вы вводите classpath звездочками «прямо» (т. Е. Непосредственно в основную оболочку, вашу основную интерактивную оболочку, свою оболочку входа), то это, вероятно, не проблема.

    Но, пожалуйста, юмористируйте меня и вставьте эту строку в кавычки.

  • Ваша проблема слишком сложная. Когда вы строите самолет, вы не строите весь самолет, а затем пытаетесь его пролететь. И затем, когда он не летает, вы не отступаете и спрашиваете: «Что случилось с самолетом?» Нет, вы проверяете его на куски. Вам нужно упростить.

    • Остановите его в фоновом режиме.
    • Прекратите говорить nohup .
    • Прекратите перенаправление вывода.
    • Не показывайте свой 42-символьный запрос командной строки в своем вопросе.
    • Ваш вопрос касается аргумента с пробелами в нем, поэтому не принимайте это, но он не должен содержать 60 символов с восемью пробелами. green bananaотличная испытательная ценность.
    • Попробуйте с аргументами вашей программы, не начиная с - (тире).
    • Возможно, даже закомментируйте new TaskRunner().run(args) вашей программы, оставив только DEBUG и System.exit(0); ,

    Ничто из этого не должно иметь значения. Но это отвлекающие факторы, из-за которых трудно понять, что важно. Если вы можете продемонстрировать проблему в минимальной тестовой конфигурации, мы можем исключить все эти вещи, связанные с проблемой. Но если проблема исчезает, когда вы удаляете ненужные вещи, то одна из них, вероятно, вызывает проблему.

    Кроме того, прекратите смешивать поддельные / тестовые данные и реальные данные (т. Е. Фрукты и задачи) в вопросе.

  • Пожалуйста, напишите этот скрипт (назовите его fruity.sh ):

     #!/bin/sh # classpath CP="/opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/*" # package.name.classname PC=wib.runner.TaskRunner "$JAVA_HOME"/bin/java -cp "$CP" "$PC" "$@" 

    и запустить

     ./fruity.sh taskExtRef "green banana" 

    Если отладка говорит

     …[taskExtRef, green banana] 

    то "$@" работает правильно, и проблема кроется в другом месте вашего скрипта. Попытайтесь найти его. Сделайте одно изменение за раз и посмотрите, как изменяется поведение. Если вы не можете понять это, мы можем помочь вам, но только если вы покажете нам часть сценария, вызывающего проблему.

    Но если отладка говорит

     …[taskExtRef, green, banana] 

    то дайте нам знать.

  • Подстановочные знаки для файловых путей не работают в grep
  • Как обрабатывать специальные символы, такие как скобка в сценарии bash?
  • Как эхо «одиночная кавычка» при использовании одиночной кавычки для обертывания специальных символов в оболочке?
  • Mutt: могу ли я определить свои собственные правила для обнаружения котируемых сообщений?
  • Почему возникает ошибка при двойном цитировании одинарных кавычек в скрипте, который запускает удаленную команду SSH?
  • Почему передача HEREDOC в виде строки для `ruby -e` не работает?
  • Escape [в grep
  • Команда SSH с перенаправлением файлов не работает
  • Как обеспечить, чтобы строка, интерполированная в подстановку sed, избегала всех метамарков
  • Bash, интересуется переменной echo $
  • Частая команда «шаблон»: удалить escape-символы расширения параметров
  • Linux и Unix - лучшая ОС в мире.