[英]How do you include a classpath wildcard as an argument to a java bash call?
[英]Using bash, how do you make a classpath out of all files in a directory?
對於一個bash大師來說,這將是一個非常簡單的免費贈品:
題
使用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變量:
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代碼將遵循:
for( each file in directory ) {
classpath = classpath + ":" + LIB + file.name
}
通過bash腳本實現此目的的簡單方法是什么?
新答案
(2012年10月)
無需手動構建類路徑列表。 Java為包含jar文件的目錄支持方便的通配符語法。
java -cp "$LIB/*"
(注意*
在引號內。)
man java
解釋:
作為一種特殊的方便,包含基本名稱*的類路徑元素被認為等同於指定擴展名為
.jar
或.JAR
的目錄中的所有文件的列表(java程序無法區分兩個調用之間的區別)。例如,如果目錄foo包含
a.jar
和b.JAR
,則類路徑元素foo/*
將擴展為A.jar:b.JAR
,但jar文件的順序未指定。 指定目錄中的所有jar文件,甚至是隱藏的文件都包含在列表中。 簡單地由*
組成的類路徑條目擴展為當前目錄中所有jar文件的列表。 定義的CLASSPATH
環境變量將同樣進行擴展。 任何類路徑通配符擴展都在Java虛擬機啟動之前發生 - 除了查詢環境之外,任何Java程序都不會看到未擴展的通配符。
老答案
簡單但不完美的解決方案:
CLASSPATH=$(echo "$LIB"/*.jar | tr ' ' ':')
有一個輕微的缺陷,這將無法正確處理帶空格的文件名。 如果重要的是嘗試這個稍微復雜的版本:
CLASSPATH=$(find "$LIB" -name '*.jar' -printf '%p:' | sed 's/:$//')
這僅在您的find命令支持-printf
(如GNU find
)時才有效。
如果你沒有GNU find
,就像在Mac OS X上一樣,你可以使用xargs
代替:
CLASSPATH=$(find "." -name '*.jar' | xargs echo | tr ' ' ':')
另一種(更奇怪的)方法是更改字段分隔符變量$IFS
。 這看起來非常奇怪,但對所有文件名都表現良好,只使用shell內置函數。
CLASSPATH=$(JARS=("$LIB"/*.jar); IFS=:; echo "${JARS[*]}")
說明:
JARS
設置為文件名數組。 IFS
更改為:
。 $IFS
用作數組條目之間的分隔符。 這意味着文件名在它們之間用冒號打印。 所有這些都是在子shell中完成的,因此$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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.