无法从java程序执行R脚本?

无法从java程序执行R脚本?,java,r,bash,runtime,processbuilder,Java,R,Bash,Runtime,Processbuilder,我在字符串变量中有一个Rscript,我想从Java程序中执行它,并向它传递一些变量。如果我独立执行R脚本,它就可以正常工作。我使用Python程序将R脚本转换为一行,将其全部转义,如下所示: import json jsonstr = json.dumps({"script": """\ #!/usr/bin/Rscript # read the data file library('jsonlite') library('rpart') args <- as.list(Sys.g

我在字符串变量中有一个Rscript,我想从Java程序中执行它,并向它传递一些变量。如果我独立执行R脚本,它就可以正常工作。我使用Python程序将R脚本转换为一行,将其全部转义,如下所示:

import json

jsonstr = json.dumps({"script": """\
#!/usr/bin/Rscript

# read the data file
library('jsonlite')
library('rpart')

args <- as.list(Sys.getenv(c(
                        "path",
                        "client_users")))

if (args[["path"]]==""){
    args[["path"]] <- "."
}

# other stuff here
# other stuff here

"""})

print jsonstr
上面的代码可以与bashshell脚本配合使用。有什么我需要做的R脚本特别?对于bash脚本和R脚本,我也将使用相同的代码

这就是我得到的错误:

/bin/bash: line 7: -: No such file or directory /bin/bash: line 10: syntax error near unexpected token `'jsonlite'' /bin/bash: line 10: `library('jsonlite')' 
如果我删除commandList.add(“/bin/bash”)和add
commandList.add(“/bin/Rscript”)然后我看到以下错误:

Cannot run program "/bin/Rscript": error=2, No such file or directory
更新:-

我没有使用上面的脚本,而是决定在r中使用简单的print hell脚本,看看是否可以通过Java执行它

// this will print hello
String script = "#!/usr/bin/env Rscript\nsayHello <- function(){\n   print('hello')\n}\n\nsayHello()\n";
但是如果我用这个
commandList.add(“/bin/sh”)执行,我得到这个错误:

/bin/bash: line 2: syntax error near unexpected token `('
/bin/bash: line 2: `sayHello <- function(){'
/bin/sh: 2: Syntax error: "(" unexpected

您必须直接运行
/usr/bin/Rscript
。此外,此程序不会从标准输入读取脚本(您必须将脚本的路径指定为
Rscript
的参数),因此您必须:

  • 创建一个临时文件
  • 写剧本
  • 使用Rscript执行脚本
  • 删除临时文件(作为一种良好的编程实践)
例如,这是一个POC:

public static void main(String[] args) throws IOException, InterruptedException {

    // Your script
    String script = "#!/usr/bin/env Rscript\n" +
            "\n" +
            "sayHello <- function() {\n" +
            "    print('hello')\n" +
            "}\n" +
            "\n" +
            "sayHello()\n";

    // create a temp file and write your script to it
    File tempScript = File.createTempFile("test_r_scripts_", "");
    try(OutputStream output = new FileOutputStream(tempScript)) {
        output.write(script.getBytes());
    }

    // build the process object and start it
    List<String> commandList = new ArrayList<>();
    commandList.add("/usr/bin/Rscript");
    commandList.add(tempScript.getAbsolutePath());
    ProcessBuilder builder = new ProcessBuilder(commandList);
    builder.redirectErrorStream(true);
    Process shell = builder.start();

    // read the output and show it
    try(BufferedReader reader = new BufferedReader(
            new InputStreamReader(shell.getInputStream()))) {
        String line;
        while((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }

    // wait for the process to finish
    int exitCode = shell.waitFor();

    // delete your temp file
    tempScript.delete();

    // check the exit code (exit code = 0 usually means "executed ok")
    System.out.println("EXIT CODE: " + exitCode);
}
public static void main(String[] args) throws IOException, InterruptedException {

    // Your script
    String script = "#!/usr/bin/env Rscript\n" +
            "\n" +
            "sayHello <- function() {\n" +
            "    print('hello')\n" +
            "}\n" +
            "\n" +
            "sayHello()\n";

    // create a temp file and write your script to it
    File tempScript = File.createTempFile("test_r_scripts_", "");
    try(OutputStream output = new FileOutputStream(tempScript)) {
        output.write(script.getBytes());
    }

    // build the process object and start it
    List<String> commandList = new ArrayList<>();
    commandList.add("/usr/bin/Rscript");
    commandList.add(tempScript.getAbsolutePath());
    ProcessBuilder builder = new ProcessBuilder(commandList);
    builder.redirectErrorStream(true);
    Process shell = builder.start();

    // read the output and show it
    try(BufferedReader reader = new BufferedReader(
            new InputStreamReader(shell.getInputStream()))) {
        String line;
        while((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }

    // wait for the process to finish
    int exitCode = shell.waitFor();

    // delete your temp file
    tempScript.delete();

    // check the exit code (exit code = 0 usually means "executed ok")
    System.out.println("EXIT CODE: " + exitCode);
}
...

// create a temp file and write your script to it
File tempScript = File.createTempFile("test_r_scripts_", "");
tempScript.setExecutable(true);
try(OutputStream output = new FileOutputStream(tempScript)) {
    output.write(script.getBytes());
}

// build the process object and start it
List<String> commandList = new ArrayList<>();
commandList.add(tempScript.getAbsolutePath());
ProcessBuilder builder = new ProcessBuilder(commandList);

...