65 votes

Avec bash, comment voulez-vous faire un chemin de classe de tous les fichiers dans un répertoire

Ce sera vraiment simple cadeau pour un bash gourou:

Question

Avec bash, comment voulez-vous faire un chemin de classe de tous les fichiers dans un répertoire?


Détails

Compte tenu d'un répertoire:

LIB=/path/to/project/dir/lib

qui ne contient rien, mais *.les fichiers jar tels que:

junit-4.8.1.jar
jurt-3.2.1.jar
log4j-1.2.16.jar
mockito-all-1.8.5.jar

J'ai besoin de créer un, séparés par deux points variable classpath de la forme:

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

Certains seudo-code que près exprime la logique, que je suis à la recherche pour être le long des lignes de:

for( each file in directory ) {
   classpath = classpath + ":" + LIB + file.name
}

Qu'est ce qu'un simple moyen pour y parvenir via script bash?

119voto

John Kugelman Points 108754

Nouvelle Réponse
(Octobre 2012)

Il n'y a pas besoin de créer manuellement le chemin de la classe liste. Java supporte une pratique syntaxe générique pour les répertoires contenant les fichiers jar.

java -cp "$LIB/*"

(Notez que l' * est à l'intérieur des guillemets.)

Explication de man java:

Comme une commodité particulière, un chemin de classe de l'élément contenant un nom de base de * est considérée comme équivalente à la spécification d'une liste de tous les fichiers dans le répertoire avec l'extension .jar ou .JAR (un programme java ne peut pas faire la différence entre les deux invocations).

Par exemple, si le répertoire foo contient a.jar et b.JAR, puis le chemin de classe de l'élément foo/* est élargi à un A.jar:b.JAR, sauf que l'ordre des fichiers jar est pas spécifié. Tous les fichiers jar dans le répertoire spécifié, même ceux qui sont cachés, sont inclus dans la liste. Un classpath composé simplement d' * se développe à une liste de tous les fichiers jar dans le répertoire courant. L' CLASSPATH variable d'environnement, où défini, sera également élargi. Tout classpath générique expansion se produit avant que la machine virtuelle Java est lancé — pas de programme Java verra jamais non développé des caractères génériques, sauf par l'interrogation de l'environnement.


Vieille Réponse

Bon

Simple, mais pas de solution parfaite:

CLASSPATH=$(echo "$LIB"/*.jar | tr ' ' ':')

Il y a une légère faille dans que cela ne va pas gérer les noms de fichiers avec des espaces correctement. Si ce qui compte essayer un peu plus compliqué que la version:

Mieux

CLASSPATH=$(find "$LIB" -name '*.jar' -printf '%p:' | sed 's/:$//')

Cela ne fonctionne que si votre commande rechercher soutient -printf (comme GNU find t).

Si vous n'avez pas de GNU find, comme sur Mac OS X, vous pouvez utiliser xargs à la place:

CLASSPATH=$(find "." -name '*.jar' | xargs echo | tr ' ' ':')

Le mieux?

Une autre (la plus étrange façon de le faire est de changer le séparateur de champ variable $IFS. C'est très étrange, à la recherche, mais se comporte bien avec tous les noms de fichier et utilise uniquement shell built-ins.

CLASSPATH=$(JARS=("$LIB"/*.jar); IFS=:; echo "${JARS[*]}")

Explication:

  1. JARS est un tableau de noms de fichiers.
  2. IFS est changé en :.
  3. Le tableau est fait l'écho, et $IFS est utilisé comme séparateur entre le tableau des entrées. Sens les noms de fichiers sont imprimés avec des points entre eux.

Tout cela est fait dans un sous-shell, donc le changement d' $IFS n'est pas permanente (ce qui serait odiiieux).

8voto

biziclop Points 21446
for i in $LIB/*.jar; do
    CLASSPATH=$CLASSPATH:$i
done
CLASSPATH=`echo $CLASSPATH | cut -c2-`

2voto

Dennis Williamson Points 105818

Voici une autre variante:

printf -v CLASSPATH "$LIB/%s:" *.jar; CLASSPATH=${CLASSPATH%:}

printf -v est un peu comme sprintf. L'attelle d'extension supprime le supplément du côlon à partir de la fin.

0voto

SiegeX Points 32614

Bestest

Tout est mieux avec awk =)

CLASSPATH=$(awk '$0=lib"/"FILENAME' ORS=":" lib=$LIB *.jar)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X