Пространство в аргументах командной строки Java - PullRequest
28 голосов
/ 13 апреля 2009

В моих аргументах командной строки Java любые символы после пробела игнорируются. Например,

java test.AskGetCampaignByName "Dummy books"

Первый аргумент (args [0]) я получаю только как "Dummy". Одиночные кавычки тоже не помогают. Есть ли обходной путь / исправить это? Может ли это быть из-за настроек моего терминала?

Мой $ TERM - это xterm, а $ LANG - "en_IN".

Ответы [ 5 ]

54 голосов
/ 13 апреля 2009

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

Поскольку вы уже процитировали аргумент, он должен работать. Единственное возможное объяснение, которое я могу придумать, - это если ваша команда java является сценарием-оберткой и портит экранирование аргументов при передаче в реальную программу. Это легко сделать, или, возможно, немного сложно сделать правильно.

Правильный скрипт-обертка должен передавать все свои аргументы как ${1+"$@"}, и любая другая версия, скорее всего, является ошибкой в ​​отношении возможности правильно обрабатывать встроенные пробелы. Это не редкость для правильного выполнения, однако также любые случаи $2 или аналогичные являются проблематичными и должны быть записаны как "$2" (или, возможно, ${2+"$2"}), чтобы правильно обрабатывать встроенные пространства, и это грешит против многих .

Причина не столь интуитивного синтаксиса ${1+"$@"} заключается в том, что исходный $* объединил все аргументы как "$1 $2 $3 ...", который не работал для встроенных пространств. Затем было введено "$@", которое (правильно) расширено до "$1" "$2" "$3" ... для всех параметров, и если параметры не заданы, оно должно расшириться до нуля. К сожалению, некоторые поставщики Unix испортили и заставили "$@" расширяться до "" даже в случае отсутствия аргументов, и чтобы обойти это, был изобретен хитрый (но не очень читаемый) способ написания ${1+"$@"}, что сделало только "$@" раскрыть, если задан параметр $1 (т.е. избежать раскрытия в случае отсутствия аргументов).

Если мое предположение об ошибке неверно, вы можете попробовать отладить с помощью strace :

strace -o outfile -f -ff -F java test.AskGetCampaignByName "Dummy books"

и выясните, какие аргументы передаются execve. Пример выполнения "strace /bin/echo '1 2' 3":

execve("/bin/echo", ["/bin/echo", "1 2", "3"], [/* 93 vars */]) = 0
brk(0)                                  = 0x2400000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075b000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075a000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib64/alliance/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/alliance/lib/tls/x86_64", 0x7fff08757cd0) = -1 ENOENT (No such file or directory)
open("/usr/lib64/alliance/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
...
1 голос
/ 05 марта 2012

Вы просто должны покинуть пробелы, как это:

normal String: "Hello World!"
escaped String: "Hello" "World!"

Это сработало для меня.

Мое окружение:

23:39:19 Zarathustra@thora:/Users/Zarathustra~$bash -version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
Copyright (C) 2007 Free Software Foundation, Inc.
0 голосов
/ 25 января 2011

Просто соберите аргументы в вашей Java-программе:

StringBuilder allArgs = new StringBuilder();
for (int i=0; i < args.length; i++)
{
    //System.out.println("arg"+i+": "+args[i]);
    allArgs.append(args[i]+" ");
}
// Parse out the args the way you wish using allArgs
0 голосов
/ 13 апреля 2009

Похоже, вы используете дистрибутив операционной системы, где доступная пользователю команда java является оберткой, которая находит нужную JVM "где-то" и соответственно вызывает ее.

Если это так, то, скорее всего, он не экранирует аргументы должным образом при вызове фактического java исполняемого файла.

Какой дистрибутив вы используете?

0 голосов
/ 13 апреля 2009

Если вашей программе нужно больше, чем позиционные аргументы (= когда важно использование командной строки), вы должны рассмотреть опции и переключатели. У Apache Commons есть отличная библиотека для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...