Не *_*еня 11 java shell exec processbuilder
我正在寻找一种最有效的方法来决定:
众所周知,要从Java启动shell脚本,应该启动shell:
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "script.sh", "arg1", "arg2);
Run Code Online (Sandbox Code Playgroud)
要启动二进制文件,应该启动二进制文件:
ProcessBuilder pb = new ProcessBuilder("/path/binary", "arg1", "arg2);
Run Code Online (Sandbox Code Playgroud)
如果使用shell执行二进制文件,则会产生错误:
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2);
(sh: cannot execute binary file)
Run Code Online (Sandbox Code Playgroud)
如果在没有shell二进制文件的情况下执行shell脚本,则会产生错误:
ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2);
(error 2: file not found)
Run Code Online (Sandbox Code Playgroud)
我的情况是我的应用程序不知道它的启动,二进制或脚本.
启动的应用程序是最终用户提供的事件处理程序.它很可能是在Unix下执行的shell脚本; 但它可以是Windows下的*.cmd,或者是在一些不起眼的平台下执行的Perl脚本.毕竟它是Java.
我的第一个天真的尝试是用shell启动命令行,看它是否有效.如果没有,请尝试将其作为二进制文件执行.
这是丑陋和冒险的:在平台和shell的一些未知组合下,第二次运行仍然可能仍然执行脚本,第二次,具有不可预测的结果.
此外,我无法判断脚本何时启动正常并且由于某些问题而失败,因为我无法启动它.
我现在正在考虑的最好的事情是:
如果您有任何更好的想法,请告知.
更新/部分解决方案
感谢所有与我分享他们想法的人.
事实证明,我把自己和互联网的其他部分弄糊涂了:)
在用户输入的命令行之前不需要在应用二进制文件前加前缀,前提是:
当我测试我的代码时,这些条件中的一个或另一个没有达到.:-(
从临时脚本执行测试后,脚本已经执行完毕.
第3点只能由用户完成,并且必须在用户手册中记录.
由于这些脚本传播到目标系统的方式,它们可能不可执行,可能不在PATH中.
我关心的唯一路径是相对路径,因此将./添加到任何相对路径就足够了.
使脚本在Unix(以及任何其他平台)下可执行是一个更大的挑战.这不是WORA.在它前面放置/ bin/sh可能会有所帮助,但如果我记得在Solaris下,shell将不会执行不可执行的脚本.
我将在本周晚些时候发布另一个更新.
一种可能的解决方案是生成一个脚本,将程序中的执行脚本/二进制文件包装起来。这样你就知道它始终是一个脚本。生成的脚本只是执行内部脚本/二进制文件并返回错误代码(并且可能重定向输入/输出)。完成后,您可以简单地将其删除。Java 允许您非常轻松地创建临时文件。