これはreally bash guruの簡単な無料サービスです:
質問
Bashを使用して、ディレクトリ内のすべてのファイルからクラスパスを作成するにはどうすればよいですか?
詳細
ディレクトリが与えられた場合:
LIB=/path/to/project/dir/lib
次のような* .jarファイルのみが含まれます。
junit-4.8.1.jar
jurt-3.2.1.jar
log4j-1.2.16.jar
mockito-all-1.8.5.jar
コロンで区切られたクラスパス変数を次の形式で作成する必要があります。
CLASSPATH=/path/to/project/dir/lib/junit-4.8.1.jar:/path/to/project/dir/lib/jurt-3.2.1.jar:/path/to/project/dir/lib/log4j-1.2.16.jar:/path/to/project/dir/lib/mockito-all-1.8.5.jar
私が探しているロジックをほぼ表現しているseudo-codeは、次のようなものです。
for( each file in directory ) {
classpath = classpath + ":" + LIB + file.name
}
simple bashスクリプトでこれを実現する方法とは何ですか?
新しい回答
(2012年10月)
クラスパスリストを手動で作成する必要はありません。 Javaは、jarファイルを含むディレクトリの便利なワイルドカード構文をサポートします。
Java -cp "$LIB/*"
(*
はinside引用符であることに注意してください。)
man Java
からの説明:
特別な便宜のため、*のベース名を含むクラスパス要素は、拡張子が
.jar
または.JAR
(Javaのディレクトリ内のすべてのファイルのリストを指定することと同等と見なされます_プログラムは、2つの呼び出しの違いを判別できません)。たとえば、ディレクトリfooに
a.jar
およびb.JAR
が含まれている場合、jarファイルの順序が指定されていないことを除き、クラスパス要素foo/*
はA.jar:b.JAR
に展開されます。指定されたディレクトリ内のすべてのjarファイルは、隠しファイルも含め、リストに含まれます。*
のみで構成されるクラスパスエントリは、現在のディレクトリ内のすべてのjarファイルのリストに展開されます。CLASSPATH
環境変数(定義されている場合)も同様に展開されます。クラスパスのワイルドカード拡張は、Java仮想マシンが起動する前に発生します。Javaプログラムは、環境を照会することを除いて、拡張されていないワイルドカードを認識しません。
旧回答
シンプルだが完璧ではないソリューション:
CLASSPATH=$(echo "$LIB"/*.jar | tr ' ' ':')
スペースを含むファイル名を正しく処理できないというわずかな欠陥があります。それが問題になる場合は、もう少し複雑なバージョンを試してください。
CLASSPATH=$(find "$LIB" -name '*.jar' -printf '%p:' | sed 's/:$//')
これは、findコマンドが-printf
をサポートしている場合にのみ機能します(GNU find
がサポートします)。
Mac OS XのようにGNU find
がない場合は、代わりにxargs
を使用できます。
CLASSPATH=$(find "." -name '*.jar' | xargs echo | tr ' ' ':')
別の(より奇妙な)方法は、フィールド区切り変数$IFS
を変更することです。これは非常に奇妙に見えますが、すべてのファイル名でうまく動作し、Shellビルトインのみを使用します。
CLASSPATH=$(JARS=("$LIB"/*.jar); IFS=:; echo "${JARS[*]}")
説明:
JARS
はファイル名の配列に設定されます。IFS
は:
に変更されます。$IFS
が配列エントリ間の区切り文字として使用されます。ファイル名の意味は、コロンで区切られて出力されます。これらはすべてサブシェルで実行されるため、$IFS
への変更は永続的ではありません(これはbaaaadになります)。
for i in $LIB/*.jar; do
CLASSPATH=$CLASSPATH:$i
done
CLASSPATH=`echo $CLASSPATH | cut -c2-`
別のバリエーションがあります:
printf -v CLASSPATH "$LIB/%s:" *.jar; CLASSPATH=${CLASSPATH%:}
printf -v
はsprintf
に似ています。ブレースを展開すると、余分なコロンが末尾から削除されます。
すべてはawk
=の方が良い
CLASSPATH=$(awk '$0=lib"/"FILENAME' ORS=":" lib=$LIB *.jar)