
Ich richte einen Java-Klassenpfad in einem Bash-Skript ein. Ich dachte, ich müsste Anführungszeichen verwenden, um zu verhindern, dass die Shell den Klassenpfad erweitert, *
basierend auf dieser Frage:https://stackoverflow.com/questions/219585/setting-multiple-jars-in-java-classpath, aber Folgendes funktioniert auch ohne Anführungszeichen:
classpath=/jars/*:/anotherJarsDir/*
java -classpath=$classpath com.test.MyClass
Shell erweitert dies jedoch:
classpath=/jars/*
java -classpath=$classpath com.test.MyClass
Es scheint, dass ich mir keine Sorgen machen muss, dass die Shell-Erweiterung meinen Java-Klassenpfad durcheinanderbringt, wenn die Klassenpfadvariable mehrere Verzeichnisse enthält?
Antwort1
classpath=
ist die Shell-Syntax zum Zuweisen einer Variablen, damit die Shell weiß, dass das Ergebnis danach ein zu erweiternder Pfad sein kann. Das bedeutet, wir müssen uns /jars/*
und ansehen /jars/*:/anotherJarsDir/*
. Das erste hat ein Verzeichnispräfix und ein Platzhalterzeichen, das zweite wird als „jede Datei in einem Verzeichnis mit dem Namen anotherJarsDir
, in einem Verzeichnis, das mit einem Doppelpunkt endet (dies ist das *:
), im /jars
Verzeichnis“ interpretiert.
Beachten Sie, dass die Shell nicht erkennt, dass der Doppelpunkt ein Pfadtrennzeichen ist; sie interpretiert ihn als Teil des Verzeichnisnamens. Wenn Sie eine Datei hätten /jars/wx:/anotherJarsDir/yz
, würde Ihr Pfad damit übereinstimmen, aber mehrere Dateien wären durch Leerzeichen und nicht durch Doppelpunkte getrennt, und Java würde dies wiederum als eine /jars/wx
Datei und eine /anotherJarsDir/yz
Datei interpretieren (vorausgesetzt, dies ist die einzige Datei, sodass Ihr Klassenpfad keine Leerzeichen enthält).
Fazit: Wenn Sie eine Erweiterung vermeiden möchten, setzen Sie Ihre Zeichenfolgen in Anführungszeichen, auch wenn in Sonderfällen eine Zeichenfolge ohne Anführungszeichen funktioniert!
Antwort2
Die Shell erweitert Platzhalter nur, wenn Übereinstimmungen vorliegen. Wenn keine Dateien dem Muster entsprechen, bleibt der Platzhalter erhalten. Java und die Shell sind sich jedoch nicht einig, was das :
Zeichen eigentlich bedeutet. In der Umgebungsvariable classpath wird es als Trennzeichen zwischen verschiedenen Elementen verwendet. Die Shell hingegen betrachtet es als gültiges Verzeichniszeichen wie jedes andere. Der einzige Grund, warum das erste Beispiel nicht erweitert wird, ist, dass es /jars/*:/anotherJarsDir/*
zufällig mit keinem Verzeichnis übereinstimmt. Wenn Sie wider Erwarten ein Verzeichnis mit einem Namen wie haben würden /jars/123:/anotherJarsDir/456
, würden die Platzhalter erweitert, um dies widerzuspiegeln. Mit anderen Worten: Setzen Sie Ihre classpath
Definition immer in Anführungszeichen.