可能重复:
执行shell脚本中的JAR文件中。 如何提取?
我有“引擎”包内打包到我的JAR文件中的shell脚本。
在我的程序我使用过程和运行的ProcessBuilder shell命令。 这一切工作正常。
如果我指定我的电脑上的路径,shell脚本则程序工作正常。 然而,如果我包的shell脚本到我的JAR和访问它是这样的:
scriptLocation = this.getClass().getResource("/engine/shell-script.sh").toString();
并运行该程序,然后我得到以下错误:
java.io.IOException: Cannot run program "file:/Users/USERNAME/Desktop/Application-Name.jar!/engine/shell-script.sh": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:460)
at java.lang.Runtime.exec(Runtime.java:593)
at java.lang.Runtime.exec(Runtime.java:431)
at java.lang.Runtime.exec(Runtime.java:328)
at engine.Download$1.run(Download.java:39)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:53)
at java.lang.ProcessImpl.start(ProcessImpl.java:91)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:453)
... 5 more
我开始觉得这不能做,我非常希望提供这个shell脚本作为应用程序的一部分,能不能做到?
在此先感谢大家。
======== UPDATE ==========
我终于解决了这个问题。 壳牌可不是一个JAR包内执行脚本,它不是关于Java,但外壳。 我解决了这个问题通过执行以下操作:
Java有一个createTempFile()方法(有选项删除该文件一旦应用程序已终止),调用此,写要访问这个临时文件的JAR包内的文件。 然后,您可以在本地文件系统的shell脚本,并能够执行脚本。
它不是关于Java,其对外壳。 据我所知,命令解释程序不能执行驻留在zip文件脚本。 所以,你有两个选择在这里:
从你的java程序中读取shell脚本为文本文件。 创建中的临时文件(在临时目录或任何其他相关地方和复制文件存在的内容。然后调用命令解释程序与此时间脚本。我相信它的最好的办法
由于罐子是一个zip,可以从外壳内将它解压缩找到一个脚本,并执行shell。 再次,这是更加尴尬,而错的,但在技术上它应该工作。
如果你不具备低层次的东西在你的脚本,你可以考虑重写逻辑Groovy脚本(也许你会发现有用groosh项目)。 然后调用从内存中的Groovy代码,而不是从文件中。
嗯,我的想法,如果我是你,我将实现第一个解决方案:)祝你好运,希望这有助于
最简单的解决办法是让你的应用程序中提取的shell脚本到一个临时位置,并从那里执行它。
你可以通过调用产生Java中的临时文件File.createTempFile(String, String)
。
那你可能做的另一件事是通过脚本的内容,从你的罐子装,作为外壳的标准输入。
作为一种简化,如果我有一个存档a.zip
包含脚本a.sh
,这将执行它:
$ unzip -p a.zip a.sh | bash
从Java程序,你可以做到以下几点:
import java.io.*;
class Test{
public static void main(String[]args) throws Exception {
StringBuilder sb = new StringBuilder();
// You're not strictly speaking executing a shell script but
// rather programatically typing commands into the shell
// sb.append("#!/bin/bash\n");
sb.append("echo Hello world!\n");
sb.append("cd /tmp\n");
sb.append("echo current directory: `pwd`\n");
// Start the shell
ProcessBuilder pb = new ProcessBuilder("/bin/bash");
Process bash = pb.start();
// Pass commands to the shell
PrintStream ps = new PrintStream(bash.getOutputStream());
ps.println(sb);
ps.close();
// Get an InputStream for the stdout of the shell
BufferedReader br = new BufferedReader(
new InputStreamReader(bash.getInputStream()));
// Retrieve and print output
String line;
while (null != (line = br.readLine())) {
System.out.println("> "+line);
}
br.close();
// Make sure the shell has terminated, print out exit value
System.out.println("Exit code: " + bash.waitFor());
}
}
我通常只是做...
$ jar xf myapp.jar run.sh && ./run.sh && rm run.sh
...您可以从的Runtime.exec()如有需要请来电。