Używając bash, jak zrobić classpath ze wszystkich plików w katalogu?
To będzie naprawdę. simple freebie for a bash guru:
Pytanie
Używając bash, jak zrobić classpath ze wszystkich plików w katalogu?
Szczegóły
Podany katalog:
LIB=/path/to/project/dir/lib
Który zawiera tylko *.pliki jar takie jak:
junit-4.8.1.jar
jurt-3.2.1.jar
log4j-1.2.16.jar
mockito-all-1.8.5.jar
Muszę utworzyć zmienną classpath rozdzieloną dwukropkami w postaci:
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
Jakiś seudo-kod, który prawie wyraża logikę, której szukam byłoby na wzór:
for( each file in directory ) {
classpath = classpath + ":" + LIB + file.name
}
Co to jest proste sposób, aby to osiągnąć za pomocą skryptu bash?
4 answers
Nowa Odpowiedź
(Październik 2012)
Nie ma potrzeby ręcznego budowania listy classpath. Java obsługuje wygodną składnię symboli wieloznacznych dla katalogów zawierających pliki jar.
java -cp "$LIB/*"
(zauważ, że *
jest wewnątrz cytatów.)
Wyjaśnienie z man java
:
Dla specjalnej wygody, element ścieżki klasy zawierający nazwę podstawową * jest uważany za równoważny z określeniem listy wszystkich plików w katalog z rozszerzeniem
.jar
lub.JAR
(program java nie potrafi odróżnić obu wywołań).Na przykład, jeśli katalog foo zawiera
a.jar
ib.JAR
, to element ścieżki klasyfoo/*
jest rozszerzony doA.jar:b.JAR
, z tym że kolejność plików jar nie jest określona. Wszystkie pliki jar w podanym katalogu, nawet ukryte, są zawarte na liście. Wpis classpath składający się po prostu z*
rozszerza się do listy wszystkich plików jar w bieżącym katalog. Zmienna środowiskowaCLASSPATH
, o ile zostanie zdefiniowana, zostanie podobnie rozwinięta. Każde rozszerzenie wildcard classpath występuje przed uruchomieniem maszyny wirtualnej Java - żaden program Java nigdy nie zobaczy niewykorzystanego wildcard, z wyjątkiem zapytań środowiska.
Stara Odpowiedź
Dobry
Proste, ale nie idealne rozwiązanie:
CLASSPATH=$(echo "$LIB"/*.jar | tr ' ' ':')
Jest drobna wada w tym, że nie będzie poprawnie obsługiwać nazw plików ze spacjami. Jeśli to ma znaczenie, spróbuj. ta nieco bardziej skomplikowana wersja:
Lepiej
CLASSPATH=$(find "$LIB" -name '*.jar' -printf '%p:' | sed 's/:$//')
Działa to tylko wtedy, gdy twoje polecenie find obsługuje -printf
(tak jak GNU find
).
Jeśli nie masz GNU find
, tak jak na Mac OS X, możesz użyć xargs
zamiast:
CLASSPATH=$(find "." -name '*.jar' | xargs echo | tr ' ' ':')
Najlepszy?
Innym (dziwniejszym) sposobem jest zmiana zmiennej separatora pól $IFS
. Jest to bardzo dziwnie wyglądające, ale zachowuje się dobrze ze wszystkimi nazwami plików i używa tylko powłoki wbudowane.
CLASSPATH=$(JARS=("$LIB"/*.jar); IFS=:; echo "${JARS[*]}")
Wyjaśnienie:
-
JARS
jest ustawiona na tablicę nazw plików. -
IFS
zmienia się na:
. - tablica jest wyświetlana echem, a {[19] } jest używana jako separator między wpisami tablicy. Oznacza to, że nazwy plików są drukowane z dwukropkami między nimi.
Wszystko to odbywa się w sub-powłoce, więc zmiana na $IFS
nie jest stała (co byłoby baaaad).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-12 21:38:27
for i in $LIB/*.jar; do
CLASSPATH=$CLASSPATH:$i
done
CLASSPATH=`echo $CLASSPATH | cut -c2-`
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-04 00:05:57
Oto kolejna odmiana:
printf -v CLASSPATH "$LIB/%s:" *.jar; CLASSPATH=${CLASSPATH%:}
printf -v
jest trochę jak sprintf
. Rozszerzenie klamry usuwa dodatkową okrężnicę z końca.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-19 02:04:04
Bestest
Wszystko jest lepsze z awk
=)
CLASSPATH=$(awk '$0=lib"/"FILENAME' ORS=":" lib=$LIB *.jar)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-18 23:44:24