2015-09-16 29 views
5

Tôi có một Rscript trong một biến String và tôi muốn thực hiện nó từ chương trình Java và chuyển một số biến cho nó. Nếu tôi thực thi tập lệnh R đó độc lập, nó hoạt động tốt. Tôi đã chuyển đổi mà kịch bản R để một dòng bằng cách thoát khỏi nó tất cả mọi thứ bằng cách sử dụng chương trình Python như hình dưới đây:không thể thực thi kịch bản lệnh R từ chương trình java?

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 

tôi sử dụng chuỗi in ra và lưu nó trong biến Chuỗi và sau đó tôi đang thực hiện với dưới mã và nó không hoạt động chút nào. Tôi đang chuyển biến số pathclient_users vào kịch bản lệnh trên.

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

    // this is your script in a string 
    // String script = "#!/bin/bash\n\necho \"Hello World\"\n\n readonly PARAM1=$param1\n echo $PARAM1\n\nreadonly PARAM2=$param2\n echo $PARAM2\n\n"; 
    String script = "above R Script here"; 

    List<String> commandList = new ArrayList<>(); 
    commandList.add("/bin/bash"); 

    ProcessBuilder builder = new ProcessBuilder(commandList); 
    builder.environment().put("path", "/home/david"); 
    builder.environment().put("client_users", "1000"); 
    builder.redirectErrorStream(true); 
    Process shell = builder.start(); 

    // Send your script to the input of the shell, something 
    // like doing cat script.sh | bash in the terminal 
    try(OutputStream commands = shell.getOutputStream()) { 
     commands.write(script.getBytes()); 
    } 

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

    // check the exit code 
    int exitCode = shell.waitFor(); 
    System.out.println("EXIT CODE: " + exitCode); 
} 

Mã trên hoạt động tốt với tập lệnh bash shell. Có điều gì tôi cần làm đặc biệt cho kịch bản R không? Tôi sẽ sử dụng cùng một mã cho bash script và R scripts.

Và đây là lỗi Tôi nhận:

/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')' 

Và nếu tôi loại bỏ commandList.add("/bin/bash"); và thêm commandList.add("/bin/Rscript"); sau đó tôi nhìn thấy dưới đây lỗi:

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

Cập nhật: -

Thay vì sử dụng kịch bản trên, tôi quyết định sử dụng kịch bản lệnh in đơn giản trong r để xem liệu tôi có thể thực thi nó hay không ugh Java hay không.

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

Khi tôi thực hiện kịch bản này với commandList.add("/bin/bash");, tôi nhận được lỗi này:

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

Nhưng nếu tôi thực hiện với commandList.add("/bin/sh"); này, tôi nhận được lỗi này:

/bin/sh: 2: Syntax error: "(" unexpected 

Trả lời

3

Bạn sẽ phải để chạy trực tiếp /usr/bin/Rscript. Ngoài ra, chương trình này không đọc kịch bản từ đầu vào chuẩn (bạn phải chỉ định đường dẫn đến kịch bản như một cuộc tranh cãi cho Rscript), do đó bạn sẽ phải:

  • Tạo một tập tin temp
  • Viết kịch bản của bạn
  • Execute kịch bản của bạn với Rscript
  • Xóa tập tin tạm thời của bạn (như là một thực hành lập trình tốt)

như một ví dụ, đây là một 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); 
} 

Là một thay thế, và nếu kịch bản của bạn có một "công việc" như dòng đầu tiên, bạn có thể làm những thay đổi này:

  • thiết lập thuộc tính thực thi của nó để "true"
  • sử dụng đường dẫn đến tệp tạm thời làm phần tử đầu tiên trong commandList (i. e.xóa commandList.add("/usr/bin/Rscript");)

phần của mã phải được sửa đổi sẽ là:

... 

// 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); 

... 
Các vấn đề liên quan