Ответ 1
Новый ответ
(Октябрь 2012 г.)
Нет необходимости вручную создавать список путей к классам. Java поддерживает удобный подстановочный синтаксис для каталогов, содержащих файлы jar.
java -cp "$LIB/*"
(Обратите внимание, что *
находится внутри кавычек.)
Объяснение из man java
:
В качестве особого удобства элемент пути класса, содержащий базовое имя *, считается эквивалентным заданию списка всех файлов в каталоге с расширением
.jar
или.jar
(программа java не может отличить два вызова).Например, если каталог foo содержит
a.jar
иb.JAR
, то элемент пути классаfoo/*
будет расширен доA.jar:b.JAR
, за исключением того, что порядок файлов jar не указан. Все файлы jar в указанном каталоге, даже скрытые, включены в список. Элемент classpath, состоящий просто из*
, расширяется до списка всех файлов jar в текущем каталоге. Переменная средыCLASSPATH
, где определена, будет аналогичным образом расширена. Любое расширение подстановочного типа classpath происходит до запуска виртуальной машины Java — никакая программа Java никогда не увидит незашифрованные подстановочные знаки, кроме как путем запроса среды.
Старый ответ
Хорошо
Простое, но не идеальное решение:
CLASSPATH=$(echo "$LIB"/*.jar | tr ' ' ':')
Есть небольшой недостаток в том, что это неправильно обрабатывает имена файлов с пробелами. Если это имеет значение, попробуйте эту более сложную версию:
лучше
CLASSPATH=$(find "$LIB" -name '*.jar' -printf '%p:' | sed 's/:$//')
Это работает только в том случае, если ваша команда find поддерживает -printf
(как это делает GNU find
).
Если у вас нет GNU find
, как в Mac OS X, вы можете вместо этого использовать xargs
:
CLASSPATH=$(find "." -name '*.jar' | xargs echo | tr ' ' ':')
лучше?
Другой (более странный) способ сделать это - изменить переменную разделителя полей $IFS
. Это очень странно выглядит, но будет вести себя хорошо со всеми именами файлов и использует только встроенные оболочки.
CLASSPATH=$(JARS=("$LIB"/*.jar); IFS=:; echo "${JARS[*]}")
Пояснение:
-
JARS
устанавливается в массив имен файлов. -
IFS
изменен на:
. - Массив эхом, а
$IFS
используется как разделитель между элементами массива. Значение имена файлов печатаются с двоеточиями между ними.
Все это делается в под-оболочке, поэтому изменение на $IFS
не является постоянным (это будет baaaad).