Đâ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()
và 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 và đố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.
Hi steveb, Làm việc tốt. Cảm ơn sự hỗ trợ quý giá của bạn. – Jack