Avec bash, comment voulez-vous faire un chemin de classe de tous les fichiers dans un répertoire?
Ce sera un vraiment simple cadeau pour un bash guru:
Question
À l'aide de bash, comment voulez-vous faire un chemin de classe de tous les fichiers dans un répertoire?
Détails
Donné 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 pour ce faire, via un script bash?
Vous devez vous connecter pour publier un commentaire.
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.
(Notez que le
*
est à l'intérieur de les guillemets.)Explication de
man java
:Vieille Réponse
Bonne
Simple, mais pas de solution parfaite:
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
Cela ne fonctionne que si votre commande find prend en charge
-printf
(comme GNUfind
n').Si vous n'avez pas de GNU
find
, comme sur Mac OS X, vous pouvez utiliserxargs
à la place:Mieux?
Un autre (encore plus bizarre) 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.Explication:
JARS
est un tableau de noms de fichiers.IFS
est changé à:
.$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 de
$IFS
n'est pas permanente (ce qui serait odiiieux).JARS
est également locale pour le shell interne est exécuté.java -cp "$CLASSPATH"
CLASSPATH=$(find "$LIB" -name '*.jar'|paste -sd: -)
. Ensuite, vous n'avez pas besoin de cela "bizarre" tableau bashism ou GNUfind
. (J'utilise explicite-
paramètre d'entrée ici pour faire travailler aussi pour BSDpaste
)CLASSPATH
si le$LIB
répertoire contient pas de pots, vous pouvez d'abord exécutershopt -s nullglob
.java -cp 'lib1/*:lib2/*:lib3/*'
.-c2-
param couper le faire? J'ai pensé qu'il pourrait être-c2 -
écrasé ensemble, mais qui donne des résultats différents. Si j'omets le couper en tout, j'obtiens les mêmes résultats. Qu'est-il là bas?xargs
ou la-printf
option surfind
.Voici une autre variation:
printf -v
est un peu commesprintf
. L'attelle d'extension supprime le supplément du côlon à partir de la fin.printf -v CLASSPATH "$LIB/%s" *.jar
. Bon appel sur la fuite du côlon, j'ai eu à le regarder pour voir si cela fait une différence, et apparemment il le fait, c'est valable NUL répertoire qui provoque le répertoire en cours à être recherché (qui peut ou peut ne pas être souhaitable).IFS
a une valeur autre que sa valeur par défaut (onglet espace saut de ligne), mais cela ne devrait pas affecter cette. Si vous neprintf "%s:\n" *.jar
voyez-vous des espaces? Qu'en estprintf '[%s]\n' "$LIB"
?Bestest
Tout est mieux avec
awk
=)awk: can't open file *.jar
. J'ai donc enlevé l' *.jar (puisque tous les fichiers sont petits pots dans le répertoire lib), et le script se bloque comme si l'attente d'entrée. J'ai essayé plusieurs autres modifications, mais je ne sais pas assez sur awk pour le fixer.