可能重复:
在jar文件中执行shell脚本.如何提取?
我有一个shell脚本打包到'engine'包中的JAR文件中.
在我的程序中,我使用Process和ProcessBuilder运行shell命令.一切正常.
如果我在计算机上指定shell脚本的路径,那么程序运行正常.但是,如果我将shell脚本打包到我的JAR中并像这样访问它:
scriptLocation = this.getClass().getResource("/engine/shell-script.sh").toString();
Run Code Online (Sandbox Code Playgroud)
并运行该程序,然后我收到以下错误:
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
Run Code Online (Sandbox Code Playgroud)
我开始认为这不可能完成,我非常想提供这个shell脚本作为应用程序的一部分,它可以完成吗?
在此先感谢大家.
========更新==========
我最终解决了这个问题.Shell无法在JAR包中执行脚本,它不是Java,而是shell.我通过执行以下操作来解决此问题:
Java有一个createTempFile()方法(带有终止应用程序后删除文件的选项),调用它,并在要访问此临时文件的JAR包中写入文件.然后,您可以在本地文件系统上安装shell脚本,并且能够执行该脚本.
Mar*_*nik 10
它不是关于Java,关于shell.据我所知,shell解释器无法执行驻留在zip文件中的脚本.所以你有几个选择:
从java程序中读取shell脚本作为文本文件.创建一个临时文件(在临时目录或任何其他相关位置并在那里复制文件的内容.然后用这个时间脚本调用shell解释器.我相信它是最好的方法
由于jar是一个zip,你可以从shell中解压缩,找到一个脚本并执行shell.再次这更尴尬而且相当错误,但从技术上讲它应该有效.
如果您的脚本中没有低级别的东西,您可以考虑将逻辑重写为groovy脚本(也许您会找到有用的groosh项目).然后从内存中调用groovy代码,而不是从文件中调用.
好吧,我没有想法,如果我是你,我会实施第一个解决方案:)祝你好运,希望这会有所帮助
最简单的解决方案是让您的应用程序将 shell 脚本提取到一个临时位置并从那里执行它。
您可以通过调用在 Java 中生成一个临时文件File.createTempFile(String, String)。
您可以做的另一件事是将脚本的内容(从 jar 加载)作为 shell 的标准输入传递。
为简化起见,如果我有一个a.zip包含 script的存档a.sh,这将执行它:
$ unzip -p a.zip a.sh | bash
Run Code Online (Sandbox Code Playgroud)
在 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());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13143 次 |
| 最近记录: |