为什么这个Java代码打印两个参数?

Stu*_*ent 6 java linux bash

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

class Test{

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

}
Run Code Online (Sandbox Code Playgroud)

输出:

$ java Test !clear
java Test clear
clear
Run Code Online (Sandbox Code Playgroud)

UPDATE

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

$ java Test !pwd
java Test pwd
pwd

$ java Test !ls
java Test ls
ls
Run Code Online (Sandbox Code Playgroud)

我知道这与bash中的历史扩展有关,我可以逃脱!解决这个问题的角色.

但是,我很想知道此代码将上述两行打印为输出的确切原因.有人可以解释一下吗?

Rea*_*tic 4

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

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

如果相反,你运行

java Test '!clear'
Run Code Online (Sandbox Code Playgroud)

(用单引号!)

!clearJava 将按原样获取参数,而不进行历史扩展。

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