我正在 bash 脚本中设置 java 类路径。我认为我必须使用引号来防止 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
如果 classpath 变量中有多个目录,那么看来我不必担心 shell 扩展会弄乱我的 java 类路径?
答案1
classpath=
是 shell 中为变量赋值的语法,所以 shell 知道后面的可能是需要扩展的路径。也就是说,我们必须查看/jars/*
和。第一个有目录前缀和通配符,第二个被解释为“在以冒号结尾的目录/jars/*:/anotherJarsDir/*
中名为 的目录中的任何文件(这是),在目录中”。anotherJarsDir
*:
/jars
请注意,shell 不知道冒号是路径分隔符;它将其解释为目录名称的一部分。如果您有一个文件/jars/wx:/anotherJarsDir/yz
,那么您的路径将与该文件匹配,但多个文件将用空格而不是冒号分隔,而 java 会将其解释为一个/jars/wx
文件和一个/anotherJarsDir/yz
文件(假设这是唯一的文件,因此不会导致类路径中出现空格)
结论:如果您想避免扩展,请用引号括住您的字符串,即使在特殊情况下未加引号的字符串也能起作用!
答案2
只有在有匹配项时,shell 才会扩展通配符。如果没有文件与模式匹配,则将保留通配符。但是,Java 和 shell 对于该:
字符的实际含义存在分歧。在 classpath 环境变量中,它用作不同项目之间的分隔符。另一方面,shell 将其视为与其他字符一样有效的目录字符。第一个示例没有扩展的唯一原因是因为/jars/*:/anotherJarsDir/*
恰好不匹配任何目录。如果出乎意料的是,您有一个名为 之类的目录/jars/123:/anotherJarsDir/456
,则通配符将被扩展以反映这一点。换句话说,请始终引用您的classpath
定义。