18

我用 Java 编写了一个程序,它通过命令行参数接受输入。我从命令行输入两个数字和一个运算符。要将两个数字相乘,我必须将输入输入为 eg 5 3 *,但它并没有像写的那样工作。

为什么它不*从命令行接受?

4

6 回答 6

33

这是因为*它是一个 shell 通配符:它对 shell 具有特殊含义,它在将其传递给命令之前对其进行扩展(在本例中为java)。

由于您需要文字*,因此您需要将其从外壳中转义。转义的确切方式因您的 shell 而异,但您可以尝试:

java ProgramName 5 3 "*"

或者:

java ProgramName 5 3 \*

顺便说一句,如果您想知道 shell 对 . 做了什么*,请尝试将 的内容打印String[] args到您的main方法中。您会发现它将包含您目录中文件的名称。

如果您需要将一些文件名作为命令行参数传递,这会很方便。

也可以看看

  • 维基百科:全球

    例如,如果一个目录包含两个文件,a.log那么b.log命令cat *.log将被 shell 扩展为cat a.log b.log

  • 维基百科:转义字符

    在 Bourne shell ( sh) 中,星号 ( *) 和问号 ( ?) 字符是通过通配符扩展的通配符。如果没有前面的转义字符,*当且仅当存在此类文件时,an 将扩展为工作目录中不以句点开头的所有文件的名称,否则*保持未扩展。所以要引用一个字面上称为 的文件"*",必须告诉 shell 不要以这种方式解释它,方法是在它前面加上一个反斜杠 ( \)。

于 2010-04-27T05:17:42.563 回答
5

在 MS WINDOWS 下不太正确:“java.exe”使用通配符默默地扩展命令行参数

  • *
  • ?
  • [ABC]

,但仅在最后一个组件中,所以

a/*/*

不像您预期​​的那样工作。

它还忽略条目“。” 和“..”,但确实尊重以“.”开头的其他文件名。

为了避免误解:如果我用 PROCEXP 查看正在运行的 JAVA 进程的命令行,我会看到未扩展的args!

我发现没有办法解决这个问题。换句话说:只要您在当前目录中至少有一个文件或目录,“java Calc 3 * 7”将不起作用!

这是非常丑陋的,并且似乎一直存在于所有 JRE 版本中,包括 Java 8。

有人知道如何禁用 Java 讨厌的命令行扩展吗?

于 2015-07-13T13:30:32.503 回答
4

* 在 shell 解释器中具有特殊含义。如何从字面上获得 * 取决于您使用的 shell 解释器。对于 Bash,您应该在 * 周围加上单引号,即 '*',而不是像 "*" 这样的双引号。

于 2010-04-27T05:27:47.930 回答
2

尝试*用引号包围"*". 星号是命令行上的保留符号。

于 2010-04-27T05:17:56.790 回答
1

使用单引号

java FooBar 5 3 '*'

这适用于大多数流行的 shell(包括 bash 和 ksh)。

于 2016-05-26T15:57:11.217 回答
0

扩展@Arno Unkrig 的回答:

在 Windows 上,某些 JVM 肯定会扩展“*”字符,而不是 shell 扩展路径。您可以通过编写一个打印出参数的小型 Java 程序来确认这一点:

public class TestArgs {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            System.out.println("Arg " + i + ": " + args[i]);
        }
    }
}

好消息是,有一个解决方法!您可以@filename像这样用作 JVM 的参数:

java @args.txtwhereargs.txt是一个包含每一行参数的文本文件。示例内容:

TestArgs
*

这等效于java使用两个参数TestArgs和调用*。最重要的*是,使用该@filename方法包含时不会扩展。我能够从这个页面找到详细信息。

于 2022-01-25T17:48:51.213 回答