
*
私は 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/*
。最初の構文にはディレクトリ プレフィックスとワイルドカードがあり、2 番目の構文は「 という名前のディレクトリanotherJarsDir
、コロンで終わるディレクトリ (これは です*:
)、ディレクトリ内の任意のファイル」として解釈されます/jars
。
シェルはコロンがパス区切り文字であることを認識せず、ディレクトリ名の一部として解釈することに注意してください。ファイルがある場合/jars/wx:/anotherJarsDir/yz
、パスはそれに一致しますが、複数のファイルはコロンではなくスペースで区切られ、Java はそれをファイル/jars/wx
と/anotherJarsDir/yz
ファイルとして解釈します (これが唯一のファイルであると仮定すると、クラスパスにスペースは含まれません)。
結論: 拡張を避けたい場合は、特殊なケースで引用符なしの文字列が機能する場合でも、文字列を引用符で囲んでください。
答え2
シェルは、一致するものがある場合のみワイルドカードを展開します。パターンに一致するファイルがない場合、ワイルドカードは保持されます。ただし、Java とシェルは、文字の:
実際の意味について意見が一致していません。クラスパス環境変数では、異なる項目間の区切り文字として使用されます。一方、シェルは、他の文字と同様に、これを有効なディレクトリ文字と見なします。最初の例が展開されない唯一の理由は、/jars/*:/anotherJarsDir/*
たまたまどのディレクトリにも一致しないからです。万が一、 のような名前のディレクトリがある場合/jars/123:/anotherJarsDir/456
、ワイルドカードはこれを反映して展開されます。つまり、classpath
定義は常に引用符で囲む必要があります。