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?

Author: peterh, 2011-01-19

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 i b.JAR, to element ścieżki klasy foo/* jest rozszerzony do A.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 środowiskowa CLASSPATH, 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:

  1. JARS jest ustawiona na tablicę nazw plików.
  2. IFS zmienia się na :.
  3. 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).

 107
Author: John Kugelman,
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-`
 8
Author: biziclop,
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.

 2
Author: Dennis Williamson,
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)
 0
Author: SiegeX,
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