2016-06-16 16 views
7

tôi không thể nhận kết quả system2. cố gắng thực thi tệp jar mẫu.Không thể nhận kết quả lệnh R system system2

execute_system.R:

workingDir <- "C:/Code" 
setwd(workingDir) 
command <- "java -jar sample.jar 674" 
commandResult <- system2(command, stdout="C:/Code/stdout.txt", stderr="C:/Code/stderr.txt") 
cat("commandResult: ", commandResult) 

Tôi nhận được thông báo lỗi khi tôi thực hiện execute_system.R tập tin này và tập tin trống được tạo (stdout.txt, stderr.txt)

commandResult: 127 
warning message: running command '"java -jar sample.jar 674"' had status 127 

Tôi muốn đọc kết quả lệnh system2 và cần xử lý dữ liệu kết quả.

Khi tôi thực hiện dấu nhắc lệnh tương tự, tôi đang nhận được kết quả thích hợp

C:/Code>java -jar sample.jar 123 
convert from String to int... 
Input: 123 
Value: 123 
Conversion process done!!! 

thực tế Mã Java của tôi

public class Conversion{ 
    public static void main(String args[]){ 
     System.out.println("convert from String to int..."); 
     String input = args[0]; 
     System.out.println("Input: " + input); 
     int value = Integer.valueOf(input) 
     System.out.println("Value: " + value); 
     System.out.println("Conversion process done!!!); 
    } 
} 

tôi chuyển đổi chương trình java này vào file jar thực thi (sample.jar) .

Hãy giúp tôi. Cảm ơn trước.

Trả lời

4

Sử dụng mã của bạn, nó làm việc cho tôi mà không có lỗi khi tôi đã làm như sau:

system2('java', args = c('-jar', 'sample.jar', '123'), 
     stdout = 'stdout.txt', stderr = 'stderr.txt') 

Tôi chạy này trên Mac OSX 10.10.5 (Yosemite). Các kết quả được in thành "stdout.txt".

Có vẻ như từ tài liệu cho system2, tùy chọn đầu tiên chỉ là một lệnh (nghĩa là không có đối số). Các đối số phải được xác định với tham số args.

Dưới đây là một đoạn trích từ Chi tiết phần:

Chi tiết

Không giống như các hệ thống, lệnh luôn được trích dẫn bởi shQuote, vì vậy nó phải là một lệnh duy nhất mà không đối số.

...

+0

Hi steveb, Làm việc tốt. Cảm ơn sự hỗ trợ quý giá của bạn. – Jack

9

Đây là một sai lầm dễ dàng để thực hiện.

Trước tiên, hãy xác định một số thuật ngữ:

  • tuyên bố       Đây là một đoạn mã shell mà thường thể hiện một hành động duy nhất cho vỏ để thực thi. Hành động này có thể là một shell được tạo tài liệu hoặc lệnh từ khóa cộng với các đối số, tên tệp của một đối số thực thi bên ngoài và một đối số, một lệnh ghép (chẳng hạn như khối dấu ngoặc ôm hoặc vỏ con), một đường dẫn của tất cả các bên trên hoặc danh sách lệnh tất cả những điều trên. Nhiều câu lệnh thường có thể được mã hóa tuần tự bằng cách sử dụng dấu tách câu lệnh, khác nhau theo trình bao.Ví dụ, vỏ Unix bash sử dụng dấu chấm phẩy (cho thực thi tiền cảnh) hoặc dấu và (đối với nền), trong khi vỏ Windows cmd sử dụng dấu và (for foreground).
  • lệnh       Đây là một thuật ngữ rất chung chung mà có thể tham khảo bất kỳ của các loại trên của lệnh, hoặc một tuyên bố chung, hoặc thậm chí đến nhiều câu lệnh tuần tự. Đây là loại thuật ngữ đòi hỏi ngữ cảnh để làm rõ ý nghĩa của nó.
  • đơn giản lệnh       Đây là một lệnh mà chỉ thực hiện một lớp vỏ được xây dựng trong hoặc thực thi bên ngoài. Điều này có thể xảy ra dưới dạng câu lệnh của chính chúng hoặc chúng có thể là một phần của lệnh ghép, đường ống hoặc danh sách lệnh. Trong bash shell, các phép gán biến và các chuyển hướng có thể tạo thành một phần hoặc thậm chí toàn bộ một lệnh đơn giản.
  • lệnh từ       Trong bối cảnh của một đơn đơn giản lệnh, đây là tên của chương trình mà bạn muốn chạy. Đây sẽ là tên tài liệu của một nội trang hệ vỏ, hoặc nó sẽ là tên tệp của một tệp thực thi bên ngoài. Đôi khi, điều này đôi khi được mô tả là từ đầu tiên của lệnh hoặc đối số zeroth .
  • lệnh đối số       Trong bối cảnh của một đơn đơn giản lệnh, đây là số không hay nhiều (bổ sung) lập luận trao cho các BUILTIN hoặc thực thi.
  • dòng lệnh       Thuật ngữ này mang theo nó những ý kiến ​​cho rằng nó dùng để chỉ một dòng duy nhất của mã shell. Tuy nhiên, nó thường được sử dụng nhiều hơn một cách lỏng lẻo, để mô tả bất kỳ phần mã shell nào có sẵn, thường là một phần của mã shell, mà thực tế có thể chứa các ngắt dòng, và do đó về mặt kỹ thuật bao gồm nhiều hơn một dòng văn bản. Thuật ngữ lệnh đôi khi được sử dụng làm cách viết tắt cho khái niệm này, thêm vào sự mơ hồ của nó. Cũng lưu ý rằng dòng lệnh đôi khi được sử dụng như một cách viết tắt cho các loại command-line interface của giao diện người dùng, mà không bao giờ được bao hàm bởi thuật ngữ không đủ tiêu chuẩn lệnh.
  • lệnh hệ thống       Đây là một thuật ngữ chung mà đòi hỏi bối cảnh để làm rõ ý nghĩa của nó. Nó có thể được coi là một từ đồng nghĩa cho lệnh, ngoại trừ công cụ sửa đổi bổ sung "hệ thống" cho thấy thực thi lệnh đang được bắt đầu từ ngữ cảnh có lập trình bên ngoài trình bao, chẳng hạn như phiên R.

Thiết kế của system2() chức năng dường như cho thấy rằng các tác giả chỉ nhằm mục đích nó được sử dụng để chạy lệnh đơn giản. Phải mất các lệnh từ như là đối số chức năng đầu tiên (dự kiến ​​sẽ là một chuỗi vô hướng, có nghĩa là một phần tử vector nhân vật) và đối số lệnh như lần thứ hai (cũng dự kiến ​​sẽ là một vector nhân vật, không hoặc nhiều phần tử). Đây là cách các tài liệu hướng dẫn đặt nó trong mô tả của hai đối số chức năng:

command

        lệnh hệ thống được gọi, là một chuỗi ký tự.

args

        một vector đặc trưng của lập luận để command.

Ở trên không làm cho nó hoàn toàn rõ ràng, nhưng câu đầu tiên của phần Chi tiết giúp:

Không giống như system(), command luôn được trích dẫn bởi shQuote(), vì vậy nó phải là một lệnh duy nhất mà không lập luận.

Như bạn có thể thấy, các tài liệu hướng dẫn là một chút mơ hồ ở chỗ nó ném xung quanh thuật ngữ chung lệnh mà không cần nhiều làm rõ. Họ cũng sử dụng thuật ngữ mơ hồ lệnh hệ thống, điều này cũng không giúp gì nhiều. Những gì họ có nghĩa là đối số chức năng đầu tiên command được thiết kế để trở thành một lệnh từ của một đơn giản lệnh. Nếu bạn muốn chuyển bất kỳ đối số lệnh nào, bạn phải chỉ định chúng trong đối số hàm thứ hai args.

Trong bảo vệ của tác giả, mã shell có thể phụ thuộc vào nền tảng và không nhất quán trong việc triển khai và hành vi. Để sử dụng các thuật ngữ chính xác hơn mà tôi đã xác định trong bài đăng này, các nhà văn tài liệu có nguy cơ bị lỗi, ít nhất là đối với một số hệ thống mà R mong muốn hỗ trợ. Sự mơ hồ có thể là một nơi an toàn chống lại nguy cơ lỗi hoàn toàn.

Lưu ý rằng điều này khác với chức năng lệnh hệ thống R khác, system():

command

        lệnh hệ thống được gọi, là một chuỗi ký tự.

Và trong phần Chi tiết:

command được phân tách như một lệnh cộng với lập luận tách bằng dấu cách. Vì vậy, nếu đường dẫn đến lệnh (hoặc một đối số như đường dẫn tệp) chứa dấu cách, nó phải được trích dẫn, ví dụ: bởi shQuote(). Unix-alikes truyền dòng lệnh tới shell (thường là '/bin/sh' và POSIX yêu cầu shell đó), vì vậy command có thể là bất kỳ thứ gì mà shell liên quan đến tệp thực thi, bao gồm cả shell script và nó có thể chứa nhiều lệnh cách nhau bởi ;.

Vì vậy, đối system(), hàm số đầu tiên command là một đầy đủ dòng lệnh.

Vì vậy, họ thực sự sử dụng chính xác cùng tên chức năng lập luận (command) và mô tả ("lệnh hệ thống được gọi, là một chuỗi ký tự."), Mặc dù lập luận có hai ý nghĩa hoàn toàn khác nhau giữa system()system2()! Hiểu tài liệu này thực sự yêu cầu người đọc phân tích cẩn thận.


Vì vậy, cuối cùng, chúng ta có thể hiểu được làm thế nào để sử dụng một cách chính xác system2() để gọi lệnh java mong muốn:

command <- 'java'; 
args <- c('-jar','sample.jar','674'); 
commandResult <- system2(command,args,stdout='C:/Code/stdout.txt',stderr='C:/Code/stderr.txt'); 

Chỉ cần cố gắng để làm sáng tỏ hơn nữa, nó rất hữu ích để thử nghiệm với hành vi của các hàm này bằng cách thử một số trường hợp thử nghiệm đơn giản. Ví dụ (trên vỏ bash Cygwin của tôi):

system('printf %d:%x\\\\n 31 31'); 
## 31:1f 
system2('printf',c('%d:%x\\\\n','31','31')); 
## 31:1f 

(Lưu ý rằng quadrupling của backslashes là cần thiết vì họ đi qua 3 bối cảnh suy, cụ thể là (1) chuỗi R suy đen, (2) bash (phi đơn ngữ), và (3) nội suy của lệnh printf về đối số lệnh đầu tiên của chúng ta, chúng ta cần printf để xem mã ký tự ASCII \n cuối cùng.)

Ngoài ra, cần lưu ý rằng, mặc dù system2() rõ ràng khuyến khích chỉ chạy lệnh đơn giản bởi thực thi tách từ lệnh đối số lệnh vào đối số chức năng riêng biệt, đó là rất có khả năng phá hoại ý định đó và sử dụng các siêu ký tự shell để thực thi một số mã shell không phải đơn giản thông qua giao diện system2():

system('echo a b; echo c d'); 
## a b 
## c d 
system2('echo',c('a','b; echo c d')); 
## a b 
## c d 

Đây là, tất nhiên, rất khó lường.

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