使用 bash,如何从目录中的所有文件中创建类路径? [英] Using bash, how do you make a classpath out of all files in a directory?

查看:19
本文介绍了使用 bash,如何从目录中的所有文件中创建类路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这对于 bash 大师来说真的是一个简单的免费赠品:

This will be a really simple freebie for a bash guru:

问题

使用 bash,如何从目录中的所有文件中创建类路径?

Using bash, how do you make a classpath out of all files in a directory?

详情

给定目录:

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

只包含 *.jar 文件,例如:

that contains nothing but *.jar files such as:

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

我需要以以下形式创建一个以冒号分隔的类路径变量:

I need to create a colon-separated classpath variable in the form:

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-code 将是这样的:

Some seudo-code that nearly expresses the logic I'm looking for would be along the lines of:

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

通过 bash 脚本实现此目的的简单方法是什么?

What is a simple way to accomplish this via bash script?

推荐答案

新答案
(2012 年 10 月)

无需手动构建类路径列表.Java 支持对包含 jar 文件的目录使用方便的通配符语法.

There's no need to manually build the classpath list. Java supports a convenient wildcard syntax for directories containing jar files.

java -cp "$LIB/*"

(注意 *引号内.)

(Notice that the * is inside the quotes.)

来自man java的解释:

为了特别方便,包含基名 * 的类路径元素被认为等效于指定目录中所有文件的列表,扩展名为 .jar.JAR(Java 程序无法区分两次调用之间的区别).

As a special convenience, a class path element containing a basename of * is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR (a java program cannot tell the difference between the two invocations).

例如,如果目录 foo 包含 a.jarb.JAR,则类路径元素 foo/* 扩展为a A.jar:b.JAR,但未指定 jar 文件的顺序.指定目录中的所有 jar 文件,甚至隐藏的,都包含在列表中.仅由 * 组成的类路径条目扩展为当前目录中所有 jar 文件的列表.CLASSPATH 环境变量,在定义的地方,将类似地扩展.任何类路径通配符扩展都发生在 Java 虚拟机启动之前——除非通过查询环境,否则任何 Java 程序都不会看到未扩展的通配符.

For example, if directory foo contains a.jar and b.JAR, then the class path element foo/* is expanded to a A.jar:b.JAR, except that the order of jar files is unspecified. All jar files in the specified directory, even hidden ones, are included in the list. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory. The CLASSPATH environment variable, where defined, will be similarly expanded. Any classpath wildcard expansion occurs before the Java virtual machine is started — no Java program will ever see unexpanded wildcards except by querying the environment.


旧答案

简单但不完美的解决方案:

Simple but not perfect solution:

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

有一个小缺陷,它不能正确处理带有空格的文件名.如果这很重要,请尝试这个稍微复杂一点的版本:

There's a slight flaw in that this will not handle file names with spaces correctly. If that matters try this slightly more complicated version:

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

这仅在您的 find 命令支持 -printf 时才有效(就像 GNU find 一样).

This only works if your find command supports -printf (as GNU find does).

如果你没有 GNU find,就像在 Mac OS X 上一样,你可以使用 xargs 代替:

If you don't have GNU find, as on Mac OS X, you can use xargs instead:

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

最好?

另一种(更奇怪的)方法是更改​​字段分隔符变量 $IFS.这看起来很奇怪,但对于所有文件名都表现良好,并且仅使用 shell 内置函数.

Best?

Another (weirder) way to do it is to change the field separator variable $IFS. This is very strange-looking but will behave well with all file names and uses only shell built-ins.

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

说明:

  1. JARS 设置为文件名数组.
  2. IFS 改为 :.
  3. 回显数组,$IFS 用作数组条目之间的分隔符.这意味着文件名之间用冒号打印.
  1. JARS is set to an array of file names.
  2. IFS is changed to :.
  3. The array is echoed, and $IFS is used as the separator between array entries. Meaning the file names are printed with colons between them.

所有这些都是在一个子 shell 中完成的,因此对 $IFS 的更改不是永久性的(这将是 baaaad).

All of this is done in a sub-shell so the change to $IFS isn't permanent (which would be baaaad).

这篇关于使用 bash,如何从目录中的所有文件中创建类路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆