
Bash 스크립트에서 Java 클래스 경로를 설정 중입니다. 나는 *
이 질문에 기초하여 쉘이 확장되는 것을 방지하기 위해 따옴표를 사용해야 한다고 생각했습니다 .https://stackoverflow.com/questions/219585/setting-multiple-jars-in-java-classpath, 그러나 다음은 따옴표 없이도 잘 작동합니다.
classpath=/jars/*:/anotherJarsDir/*
java -classpath=$classpath com.test.MyClass
그러나 쉘은 이것을 확장합니다:
classpath=/jars/*
java -classpath=$classpath com.test.MyClass
클래스 경로 변수에 여러 디렉토리가 있는 경우 쉘 확장으로 인해 Java 클래스 경로가 엉망이 되는 것에 대해 걱정할 필요가 없는 것 같습니다.
답변1
classpath=
변수를 할당하기 위한 쉘 구문이므로 쉘은 그 이후의 내용이 확장할 경로일 수 있음을 알고 있습니다. 즉, 우리는 /jars/*
및 를 살펴봐야 합니다 /jars/*:/anotherJarsDir/*
. 첫 번째 항목에는 디렉터리 접두사와 와일드카드가 있고, 두 번째 항목은 "라는 이름의 디렉터리 anotherJarsDir
, 콜론으로 끝나는 디렉터리( *:
)에 있는 모든 파일로 해석됩니다 /jars
.
쉘은 콜론이 경로 구분 기호라는 것을 인식하지 못합니다. 이를 디렉토리 이름의 일부로 해석합니다. file 이 있으면 /jars/wx:/anotherJarsDir/yz
경로가 일치하지만 여러 파일은 콜론이 아닌 공백으로 구분되며 java는 이를 파일 /jars/wx
과 /anotherJarsDir/yz
파일로 해석합니다(이것이 유일한 파일이라고 가정하여 결과가 발생하지 않습니다). 클래스 경로의 공백에 있음)
결론: 확장을 피하려면 문자열을 인용하십시오. 인용되지 않은 문자열이 특수한 경우에 작동하더라도 마찬가지입니다!
답변2
쉘은 일치하는 항목이 있는 경우에만 와일드카드를 확장합니다. 패턴과 일치하는 파일이 없으면 와일드카드가 유지됩니다. 그러나 Java와 쉘은 :
문자가 실제로 무엇을 의미하는지에 대해 동의하지 않습니다. 클래스 경로 환경 변수에서는 여러 항목 간의 구분 기호로 사용됩니다. 반면에 쉘은 이를 다른 것과 마찬가지로 유효한 디렉토리 문자로 간주합니다. 첫 번째 예가 확장되지 않는 유일한 이유는 /jars/*:/anotherJarsDir/*
일치하는 디렉터리가 없기 때문입니다. 역경에도 불구하고 와 같은 디렉토리가 있는 경우 /jars/123:/anotherJarsDir/456
이를 반영하기 위해 와일드카드가 확장됩니다. 즉, 항상 classpath
정의를 인용하십시오.