Java 构建jar以包含未获得执行权限的shell脚本文件
我有一个普通的java应用程序,它有一个调用Java 构建jar以包含未获得执行权限的shell脚本文件,java,maven,Java,Maven,我有一个普通的java应用程序,它有一个调用src/main/resources/*.sh下shell脚本文件的主类 我使用Runtime.getRuntime().exec(cmd)来执行脚本 String cmdPath = new this.getClass().getResource("/XXXX.sh").getPath() String[] cmd = { "bash", cmdPath }; 我的出口代码是127 1) 使用java-jar xxx.jar运行 2) sh文件的文
src/main/resources/*.sh下shell脚本文件的主类
我使用Runtime.getRuntime().exec(cmd)来执行脚本
String cmdPath = new this.getClass().getResource("/XXXX.sh").getPath()
String[] cmd = { "bash", cmdPath };
我的出口代码是127
1) 使用java-jar xxx.jar运行
2) sh文件的文件权限为-rw-rw-r--
如何获得要执行的脚本文件的文件权限
脚本文件位于src/main/resource下/
使用maven jar插件捆绑jar,脚本文件进入根目录
罐子
/-com
-软件
-cmd.sh
尝试使用带有自定义脚本的maven assembly插件向{basedir}(未在任何地方定义)下的所有文件授予755权限。它不起作用
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>ourAssembly</id>
<formats>
<format>jar</format>
</formats>
<fileSets>
<fileSet>
<directory>${basedir}</directory>
<includes>
<include>**/*</include>
</includes>
<fileMode>0755</fileMode>
</fileSet>
</fileSets>
我们的大会
罐子
${basedir}
**/*
0755
URL的getPath()
方法未返回有效的文件名。URL的“路径”只是权限后面的部分,不包括任何查询或片段。URL中不允许有很多字符,因此它们是百分比转义的,并且getPath()
将返回带有这些转义的字符串
此外,.jar条目根本不是文件,它只是.jar文件中表示压缩数据的字节序列。要执行它,您需要将它复制到一个真实的文件中,然后执行它
大概是这样的:
Path script = Files.createTempFile(null, ".sh",
PosixFilePermissions.asFileAttribute(
PosixFilePermissions.fromString("rw-rw-r--")));
try (InputStream embeddedScript =
this.getClass().getResourceAsStream("/XXXX.sh")) {
Files.copy(embeddedScript, script, StandardCopyOption.REPLACE_EXISTING);
}
String[] cmd = { "bash", script.toString() };
处理完副本后,应将其删除:
ProcessBuilder builder = new ProcessBuilder(cmd);
builder.inheritIO();
Process process = builder.start();
process.waitFor();
Files.delete(script);
如果出于某种原因不想创建tempfile,也可以执行该过程并将InputStream从getresourceastream
作为stdin传递
这是Scala,它有一个稍微不同的ProcessBuilderAPI和一个时髦的语法来传递inputstream,但同样的原则也适用
导入scala.sys.process.process
对象Sh{
def调用(resourcePath:String,args:Seq[String]):Int={
(进程(“sh”,Seq(“-s”,““--”)++args)#
如果没有-s
参数,则args将指向sh本身,而不是您的脚本
此外,如果您添加了#,这种方法仅适用于实际的shell脚本/顶部的usr/bin/python
将忽略它。exec()系统调用处理#!如果没有JNI或一些黑客,我们不能从Java调用它。太棒了!我将其复制到a/tmp文件夹并执行。成功了,谢谢!