
Я настраиваю java classpath в скрипте bash. Я думал, что мне придется использовать кавычки, чтобы предотвратить расширение shell *
на основе этого вопроса:https://stackoverflow.com/questions/219585/setting-multiple-jars-in-java-classpath, но следующее прекрасно работает и без кавычек:
classpath=/jars/*:/anotherJarsDir/*
java -classpath=$classpath com.test.MyClass
Однако shell расширит это:
classpath=/jars/*
java -classpath=$classpath com.test.MyClass
Похоже, мне не нужно беспокоиться о том, что расширение оболочки испортит мой путь к классам Java, если в переменной пути к классам есть несколько каталогов?
решение1
classpath=
— это синтаксис оболочки для назначения переменной, поэтому оболочка знает, что после может идти путь для расширения. Это значит, что нам нужно посмотреть на /jars/*
и /jars/*:/anotherJarsDir/*
. Первый имеет префикс каталога и подстановочный знак, второй интерпретируется как «любой файл в каталоге с именем anotherJarsDir
, в каталоге, заканчивающемся двоеточием (это *:
), в /jars
каталоге».
Обратите внимание, что оболочка не знает, что двоеточие является разделителем пути; она интерпретирует его как часть имени каталога. Если у вас есть файл /jars/wx:/anotherJarsDir/yz
, то ваш путь будет совпадать с ним, но несколько файлов будут разделены пробелами, а не двоеточиями, и Java, в свою очередь, интерпретирует это как файл /jars/wx
и /anotherJarsDir/yz
файл (предполагая, что это единственный файл, таким образом, не приводя к пробелам в вашем classpath)
Вывод: если вы хотите избежать расширения, заключайте строки в кавычки, даже если строка без кавычек работает в особых случаях!
решение2
Оболочка будет раскрывать подстановочные знаки только в случае совпадений. Если ни один файл не соответствует шаблону, подстановочный знак будет сохранен. Однако Java и оболочка расходятся во мнениях относительно того, что :
на самом деле означает этот символ. В переменной среды classpath он используется как разделитель между различными элементами. С другой стороны, оболочка считает его допустимым символом каталога, как и любой другой. Единственная причина, по которой первый пример не раскрывается, заключается в том, что /jars/*:/anotherJarsDir/*
он не соответствует ни одному каталогу. Если, вопреки всем шансам, у вас есть каталог с именем вроде /jars/123:/anotherJarsDir/456
, подстановочные знаки будут раскрыты, чтобы отразить это. Другими словами, всегда заключайте свое classpath
определение в кавычки.