1

在 Unix(或 Linux)中,如果我想运行一个 shell 脚本,我可以用#!/bin/sh. 使用awk,我启动可执行文件#!/usr/bin/awk -f并将文件的其余部分视为程序。

我如何用 Java 程序做到这一点?我尝试复制simple.classto simple,放在#!/export/appl/Mail/java/bin/java顶部并使文件可执行,但我得到:

69> ./simple
Error: Could not find or load main class ..simple

我知道这可以通过可执行的 shell 脚本或执行 java 解释器的 C 程序来完成。Unix 上的所有其他解释器都可以使用#!加载卡调用,当然有一种方法可以使用 Java。

4

7 回答 7

1

Java 类文件格式不允许在标头之前使用文本,这就是为什么 Java 运行时在您修改后不再接受 .class 文件的原因。

在 Linux 上,您可以使用binfmt_misc来支持其他可执行格式,包括.class文件。它基本上是一种告诉 Linux 内核如何检测可执行格式以及如何执行它们的方法。

这篇Archilinux Wiki 文章更详细地解释了如何获得这种效果。

于 2013-06-05T15:45:59.703 回答
1

最常用的方法是为 Java 提供一个包装器。执行“java -jar yourJar.jar”或等效的 shell 脚本。然后将shell脚本和 Windows 等效bat文件与您的产品捆绑在一起。

另一种选择是拥有一个原生启动器。例如,您可以看到 Eclipse 项目。您下载了 Eclipse,并且您有一个本机可执行文件可以运行。本机可执行文件将启动您的 Java 程序。

另一种选择是将Java编译为本机代码。例如,您可以使用这个名为 Excelsior JET ( http://www.excelsior-usa.com/jet.html ) 的商业工具。

于 2013-06-05T15:26:09.277 回答
0

你不能用 Java 程序来做。首先,Java 程序需要在执行前进行编译。其次,即使不需要编译,井号在 Java 中也不是注释,所以这将是一个语法错误。

于 2013-06-05T15:23:04.160 回答
0

除了其他人建议的包装脚本和 binfmt_misc 解决方案之外,我想提出一个潜在的解决方案,它不能直接回答您的问题,但也许它可以解决您的实际问题。

由于Scala确实有一个解释器可以运行代码而无需您先编译它,并且此代码可以引用任何 Java 代码,如果您的目标可以概括为“使用 Java 作为 shell 脚本语言”,您可以使用.scala文件作为您的启动脚本(可以包括要运行的 shebang scala),您可以从中调用所有 Java 类。这并不比拥有一个bash基于 - 的启动脚本更简单,但它是一个很好的起点,可以逐渐转向使用 Scala 而不是 Java 编写脚本,在这种情况下,您可以首先摆脱编译到.class文件的需要。

于 2013-06-05T19:24:23.817 回答
0

其他答案解释了为什么你不能做你想做的事。但是,如果你的 shell 是 zsh,你可以创建一个后缀别名。例如,要使用 java 执行 .jar 文件:

alias -s .jar="/usr/bin/java -jar"

然后,要执行 blarg.jar,您只需键入./blarg.jar. 当然,你必须先 chmod +x 你的 .jar 文件。

于 2013-06-05T15:45:45.663 回答
0

我从来没有听说过“加载卡”这个词。您拥有的是由shebang指定的“解释器指令” 。这仅指定 shell 应在给定脚本上调用的解释器。

至于为什么 C 程序可以直接在 shell 中运行,操作系统识别的可执行文件被传递给loader。Java 类不是可执行文件,至少对于操作系统来说是这样。所以shell必须知道将控制权传递给哪个解释器。

但正如您所注意到的,shebang 不起作用。原因是类文件是 JVM 期望的特定二进制格式。编辑此文件将打破惯例并导致错误。因此,没有办法按照您的要求进行操作。

但是,您可以通过创建别名或编写单行 Shell 脚本来包装java您需要的命令来为要运行的程序创建“快捷方式”。这是我理解的常见做法。

于 2013-06-05T15:37:46.683 回答
-1

这不起作用的原因是 Java 不是真正的解释型语言,它是部分编译、部分解释的。

将 hashbang 指令放入的 .java 源代码需要先编译为 .class 文件,然后 java 解释器才能运行它。注释被编译器去掉,因此无法将注释从 .java 推送到 .class 文件中。.class 文件是以特定格式“编译”输出的,因此在其顶部添加 hashbang 指令会破坏格式。

Java 并不是真的要成为一种脚本语言——但一些 JVM 语言是。例如, Groovy 支持 hashbangClojure 也是如此

于 2013-06-05T15:32:06.723 回答