【问题标题】:Why does this Java code print two arguments?为什么这段 Java 代码会打印两个参数?
【发布时间】:2017-12-16 23:08:41
【问题描述】:

当我将!clear 作为输入传递时,下面的 Java 代码会打印两个参数,如下所示。

class Test{

    public static void main(final String... arguments){
        for(String argument : arguments){
            System.out.println(argument);
        }
    }

}

输出:

$ java Test !clear
java Test clear
clear

更新

使用任何 linux 命令代替 clear 会产生相同的结果。

$ java Test !pwd
java Test pwd
pwd

$ java Test !ls
java Test ls
ls

我知道这与 bash 中的历史扩展有关,我可以逃脱 !字符来解决这个问题。

但是,我很想知道这段代码打印上述两行作为输出的确切原因。有人能解释一下吗?

【问题讨论】:

标签: java linux bash


【解决方案1】:

您在 Unix/Linux shell 中工作,可能是bash! 字符是 Unix shell 中的特殊字符,因此您的命令被视为历史扩展。

在历史扩展中,通常发生的事情是 shell 向您显示命令扩展的内容。 !clear 的扩展将只是 clear假设您在历史记录中有命令 clear,因此扩展的命令将是 java Test clear。然后shell 运行该命令。 Java 运行并且只看到一个参数 - clear,这就是它打印的内容。

如果相反,你运行

java Test '!clear'

(带单引​​号!)

Java 将按原样获取参数 !clear,无需历史扩展。

如果您使用的单词不在 shell 的命令历史记录中,您将收到“未找到事件错误”。如果您使用的词在您的 shell 历史记录中使用参数启动命令,则将替换整个命令及其所有参数。这都是 bash 的一部分,而不是 Java。

【讨论】:

  • 是的,我知道我可以转义输入来解决问题。谢谢你的解释。因此,Java 不会打印第一行。
  • 但是,当我在 bash 中键入 !clear 时,我没有看到任何打印内容,它只是清除了屏幕。为什么会这样?
  • @Beginner 因为当! 在命令中的第一个单词之前时,它会在历史记录中查找以该单词开头的命令,并调用它。如果你有一个以单词clear 开头的命令,shell 会记住它。而且由于它会清除屏幕,因此您几乎没有机会查看它是否打印任何内容。
  • 对不起,我还没有理解正确。即使 shell 调用 clear 为什么 clear 会打印任何东西?
  • @Beginner clear 不会打印任何内容。 shell 设置为在执行之前打印调用的命令。但是因为召回的命令会清除任何打印,我认为打印不会是可见的。
猜你喜欢
  • 2017-10-14
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
  • 2022-12-18
  • 2011-03-17
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
相关资源
最近更新 更多