如何从 Java 执行命令 R CMD Rserve
How can execute command R CMD Rserve from Java
我正在尝试使用 Runtime exec 函数从我的 java 后端启动 Rserve。我通常可以执行像 killall 这样的 linux 命令来停止进程,但我无法启动它。
您可以使用此
从命令行启动 Rserve
R CMD Rserve
并且工作正常。但是来自 java:
Process pr = Runtime.getRuntime().exec("R CMD Rserve")
它不工作。那么我如何使用 java 中的此命令?
我查看了一些文档并找到了一些东西。试试这个:
try {
String command ="R CMD Rserve";
BufferedWriter out = new BufferedWriter(new FileWriter(new File("path/to/file"), true));
final Process process = Runtime.getRuntime().exec(command);
BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = buf.readLine()) != null) {
out.write(line);
out.newLine();
}
buf.close();
out.close();
int returnCode = process.waitFor();
System.out.println("Return code = " + returnCode);
} catch (Exception e) {
e.printStackTrace();
}
如果有帮助请告诉我:)
exec
与 'it works when I type it in a shell' 不是一回事。毕竟,当您键入 'on the command line' 时,'command line' 本身就是一个应用程序。通常是/bin/bash
,但是有很多很多shell。
A shell 不只是把你输入的内容逐字地扔到 OS 然后去 'here. Run this'。它接受你输入的内容并对其进行处理。对其应用转换。 然后,被按摩的东西被扔在OS和'here, run this'。
Java 是类似的,因为它需要你写的东西,按摩它,然后把它扔到 OS。
这些按摩方式大不相同.
例如/bin/bash会把*.txt
变成运行宁ls *.txt
的结果。 Java 不会这样做,所以如果您尝试 运行 例如exec("/bin/ls *.txt")
在java 中不起作用。 ls 试图找到一个名为 *.txt
的文件,但报告找不到它。
诀窍是了解 bash 对您的输入所做的所有许多事情,并且 依赖于此 的 none。 java 对按摩的实际作用取决于 OS,所以也不要依赖于此。因此,一些规则:
始终使用绝对路径。不要运行R CMD Rserve
。 运行 /usr/local/share/R/bin/R CMD RServe
,例如。我不知道 R
在哪里,但它是您系统某处的可执行文件。找到绝对路径; bash 所做的其中一项按摩是应用 $PATH
。 Java 可能应用也可能不应用路径,谁知道你的路径设置是什么,如果 java 进程与你的 bash 具有相同的 PATH 设置;它可能不会,所以,绝对不要依赖它,并且总是,总是,写一个绝对路径。
注意 bash 内部结构,切勿使用它们。 ls
和 ps
通常是内部函数;根据定义,那么 java 不能 运行 他们。如果你必须依赖bash主义,你实际上必须运行 bash。不是 exec("ls")
,是 exec("/bin/bash", "-c", "ls")
。
永远不要依赖 java 的空间分割能力。永远不要使用 exec(cmd)
,也永远不要使用 Runtime.getRuntime().exec
。考虑这些被禁止的方法。创建一个 ProcessBuilder
,并且始终是 List<String>
变体(列表中的第一个条目是命令的 绝对 路径,其余是命令行参数.
这会让你:
// to stop
List<String> args = List.of("/bin/bash", "-c", "killall -9 RServe");
ProcessBuilder pb = new ProcessBuilder(args);
// if you need to read what bash produces, config that here.
pb.start();
// to start
List<String> args = List.of("/abs/path/to/R", "CMD", "RServe");
ProcessBuilder pb = new ProcessBuilder(args);
// if you need to read what bash produces, config that here.
pb.start();
当然,除非您的 java 进程是启动它的进程,否则您将无法 kill -9
,因此很可能无法从 java 执行此操作- 你只是没有权利。
我知道它可以改变我尝试调用流程的方式。 rzwitserloot 的回答对于解决这个问题非常有用。
我不知道“R CMD”命令的内部结构,但它不喜欢 java 进程构建器。
还有其他方法可以在 R 控制台中调用 Rserver 守护进程,所以我尝试这样做。这很好用:
List<String> args = List.of("/bin/sh", "-c","echo 'library(Rserve);Rserve(args=\"--no-save --slave\");'| /usr/lib/R/bin/R --no-save --slave");
ProcessBuilder pb = new ProcessBuilder(args);
Process p = pb.start();
我正在尝试使用 Runtime exec 函数从我的 java 后端启动 Rserve。我通常可以执行像 killall 这样的 linux 命令来停止进程,但我无法启动它。 您可以使用此
从命令行启动 RserveR CMD Rserve
并且工作正常。但是来自 java:
Process pr = Runtime.getRuntime().exec("R CMD Rserve")
它不工作。那么我如何使用 java 中的此命令?
我查看了一些文档并找到了一些东西。试试这个:
try {
String command ="R CMD Rserve";
BufferedWriter out = new BufferedWriter(new FileWriter(new File("path/to/file"), true));
final Process process = Runtime.getRuntime().exec(command);
BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = buf.readLine()) != null) {
out.write(line);
out.newLine();
}
buf.close();
out.close();
int returnCode = process.waitFor();
System.out.println("Return code = " + returnCode);
} catch (Exception e) {
e.printStackTrace();
}
如果有帮助请告诉我:)
exec
与 'it works when I type it in a shell' 不是一回事。毕竟,当您键入 'on the command line' 时,'command line' 本身就是一个应用程序。通常是/bin/bash
,但是有很多很多shell。
A shell 不只是把你输入的内容逐字地扔到 OS 然后去 'here. Run this'。它接受你输入的内容并对其进行处理。对其应用转换。 然后,被按摩的东西被扔在OS和'here, run this'。
Java 是类似的,因为它需要你写的东西,按摩它,然后把它扔到 OS。
这些按摩方式大不相同.
例如/bin/bash会把*.txt
变成运行宁ls *.txt
的结果。 Java 不会这样做,所以如果您尝试 运行 例如exec("/bin/ls *.txt")
在java 中不起作用。 ls 试图找到一个名为 *.txt
的文件,但报告找不到它。
诀窍是了解 bash 对您的输入所做的所有许多事情,并且 依赖于此 的 none。 java 对按摩的实际作用取决于 OS,所以也不要依赖于此。因此,一些规则:
始终使用绝对路径。不要运行
R CMD Rserve
。 运行/usr/local/share/R/bin/R CMD RServe
,例如。我不知道R
在哪里,但它是您系统某处的可执行文件。找到绝对路径; bash 所做的其中一项按摩是应用$PATH
。 Java 可能应用也可能不应用路径,谁知道你的路径设置是什么,如果 java 进程与你的 bash 具有相同的 PATH 设置;它可能不会,所以,绝对不要依赖它,并且总是,总是,写一个绝对路径。注意 bash 内部结构,切勿使用它们。
ls
和ps
通常是内部函数;根据定义,那么 java 不能 运行 他们。如果你必须依赖bash主义,你实际上必须运行 bash。不是exec("ls")
,是exec("/bin/bash", "-c", "ls")
。永远不要依赖 java 的空间分割能力。永远不要使用
exec(cmd)
,也永远不要使用Runtime.getRuntime().exec
。考虑这些被禁止的方法。创建一个ProcessBuilder
,并且始终是List<String>
变体(列表中的第一个条目是命令的 绝对 路径,其余是命令行参数.
这会让你:
// to stop
List<String> args = List.of("/bin/bash", "-c", "killall -9 RServe");
ProcessBuilder pb = new ProcessBuilder(args);
// if you need to read what bash produces, config that here.
pb.start();
// to start
List<String> args = List.of("/abs/path/to/R", "CMD", "RServe");
ProcessBuilder pb = new ProcessBuilder(args);
// if you need to read what bash produces, config that here.
pb.start();
当然,除非您的 java 进程是启动它的进程,否则您将无法 kill -9
,因此很可能无法从 java 执行此操作- 你只是没有权利。
我知道它可以改变我尝试调用流程的方式。 rzwitserloot 的回答对于解决这个问题非常有用。 我不知道“R CMD”命令的内部结构,但它不喜欢 java 进程构建器。 还有其他方法可以在 R 控制台中调用 Rserver 守护进程,所以我尝试这样做。这很好用:
List<String> args = List.of("/bin/sh", "-c","echo 'library(Rserve);Rserve(args=\"--no-save --slave\");'| /usr/lib/R/bin/R --no-save --slave");
ProcessBuilder pb = new ProcessBuilder(args);
Process p = pb.start();