我一直在谷歌搜索一段时间,每个人似乎都有不同的解决方案,其中任何一个似乎都不适合我。
我尝试了ProcessBuilder
和Runtime
。两者都直接调用.sh
文件并将其提供给/bin/bash
。没有运气。
回到基础,我目前的代码如下;
String cmd[] = { "~/path/to/shellscript.sh", "foo", "bar" };
Process p = Runtime.getRuntime().exec(cmd);
尽管手动运行,但出现No such file or directory
错误;
~/path/to/shellscript.sh foo bar
从bash完美运作。
我需要保留~
,因为这个shellcript以不同的形式存在于三个不同的用户。
答案 0 :(得分:13)
一种选择是自己处理~
:
String homeDir = System.getenv("HOME");
String[] cmd = { homeDir + "/path/to/shellscript.sh", "foo", "bar" };
Process p = Runtime.getRuntime().exec(cmd);
另一个是让Bash为你处理它:
String[] cmd = { "bash", "-c", "~/path/to/shellscript.sh foo bar" };
Process p = Runtime.getRuntime().exec(cmd);
答案 1 :(得分:3)
如前所述,tilde是一个特定于shell的扩展,应该通过将其替换为当前用户的主目录来手动处理(例如,如果定义了$HOME
)。
除了已经提供的解决方案,您还可以考虑使用commons-io项目中的commons-exec和Apache Commons:
...
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.Executor;
import org.apache.commons.io.FileUtils;
...
CommandLine cmd = new CommandLine("path/to/shellscript.sh");
cmd.addArgument("foo");
cmd.addArgument("bar");
Executor exec = new DefaultExecutor();
exec.setWorkingDirectory(FileUtils.getUserDirectory());
exec.execute(cmd);
...
答案 2 :(得分:1)
一般情况下,我建议您使用ScriptEngine代替System.getRuntime()。exec
我认为它会让事情变得更容易。
请记住,你需要这个JDK 6及以上版本。
此外,关于您的具体问题 - 我真的认为这个问题应该是可配置的。
您可以执行以下操作:
A.在.bash_rc或.bash_profile中(对于每个用户)使用以下内容定义配置
脚本的路径:
出口MY_SCRIPT =
B.使用
从java代码中读取此值
String sciprtPath = System.getenv("MY_SCRIPT")
获取价值。
C.运行脚本,在代码中执行的方式,使用scriptPath变量或使用scriptEngine。