gpt4 book ai didi

java - 如何在不使用通配符扩展的情况下将 * 传递给 java 程序?

转载 作者:行者123 更新时间:2023-11-30 06:17:19 25 4
gpt4 key购买 nike

考虑以下简单的 Java 程序:

import java.util.Arrays;

public class Main {
public static void main(String[] args) {
System.out.println(Arrays.asList(args));
}
}

Glob 扩展通常由 shell 完成,而不是由 JVM 完成。例如,在 Cygwin 中:

$ echo *
Main.class

这里 Cygwin 将 * 扩展为 Main.class(目录中的文件)

可以关闭此行为:

$ set -f
$ echo *
*

现在*尚未展开。

但是,当将 * 传递给 Java 程序时,通配符会以某种方式扩展:

$ set -f
$ java Main *
[Main.class]

引用或转义也没有帮助:

$ java Main '*'
[Main.class]
$ java Main \*
[Main.class]

谁是罪魁祸首,Shell 还是 Java?看起来是 JVM,因为 python 程序运行得很好:

Python 文件a.py:

import sys
print sys.argv[1:]

使用通配符运行Python程序:

$ set -f; python a.py *
['*']

没有扩展。

为什么 JVM 扩展通配符?这应该是 Shell 的函数,而不是 JVM。如何关闭此功能?

最佳答案

在 Unix 上,glob 扩展由 shell 处理,而不是由程序处理。

在 Windows 上,全局扩展由程序处理,而不是由 shell 处理。

这意味着当您从 Unix shell 运行 Windows 程序时,您可能会面临两次 glob 扩展的风险。

这是Windows OpenJDK source code负责此:

/*
* At this point we have the arguments to the application, and we need to
* check with original stdargs in order to compare which of these truly
* needs expansion. cmdtoargs will specify this if it finds a bare
* (unquoted) argument containing a glob character(s) ie. * or ?
*/
jobjectArray
CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
{
// (***snip***)
NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
"expandArgs",
"([Ljava/lang/String;)[Ljava/lang/String;"));

// expand the arguments that require expansion, the java method will strip
// out the indicator character.
NULL_CHECK0(inArray = NewPlatformStringArray(env, nargv, argc));
outArray = (*env)->CallStaticObjectMethod(env, cls, mid, inArray);

这是 expandArgs它调用:

static String[] expandArgs(List<StdArg> argList) {
ArrayList<String> out = new ArrayList<>();
// (***snip***)
try (DirectoryStream<Path> dstream =
Files.newDirectoryStream(parent.toPath(), glob)) {
int entries = 0;
for (Path p : dstream) {
out.add(p.normalize().toString());
entries++;
}

我不知道是否可以禁用此行为。考虑在文件中传递数据,或使用 Windows Subsystem for Linux,它比 CygWin 更准确地模拟 Unix 环境。

关于java - 如何在不使用通配符扩展的情况下将 * 传递给 java 程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48949668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com