2012-11-01 36 views
9

Tôi đã googling một thời gian, và tất cả mọi người dường như có một giải pháp khác nhau, không ai trong số đó xuất hiện để được làm việc cho tôi.Thực thi shell-script với các tham số từ java

Tôi đã thử cả hai ProcessBuilderRuntime. Cả hai đều gọi trực tiếp số .sh và cho vào /bin/bash. Không có may mắn.

Quay lại vấn đề cơ bản, mã hiện tại của tôi như sau;

String cmd[] = { "~/path/to/shellscript.sh", "foo", "bar" }; 
Process p = Runtime.getRuntime().exec(cmd); 

Lỗi này gây ra lỗi No such file or directory, mặc dù chạy theo cách thủ công;

~/path/to/shellscript.sh foo bar 

Hoạt động hoàn hảo từ bash.

Tôi cần giữ ~ vì shellscript này tồn tại ở các dạng hơi khác nhau cho ba người dùng khác nhau.

Trả lời

11

Một lựa chọn là để xử lý ~ mình:

String homeDir = System.getenv("HOME"); 
String[] cmd = { homeDir + "/path/to/shellscript.sh", "foo", "bar" }; 
Process p = Runtime.getRuntime().exec(cmd); 

khác là để cho Bash xử lý nó cho bạn:

String[] cmd = { "bash", "-c", "~/path/to/shellscript.sh foo bar" }; 
Process p = Runtime.getRuntime().exec(cmd); 
+0

Ah, là '~ 'có thể sẽ gây ra những vấn đề làm bạn nghĩ? Có java không biết làm thế nào để vượt qua một con đường như vậy để gọi hệ thống? – lynks

+0

Có, rất có thể ~ là lý do. Bạn có thể có gợi ý ở trên nếu mỗi người dùng tập lệnh có cùng đường dẫn tương đối trong thư mục chính hoặc có đường dẫn được định cấu hình cho mỗi người dùng, như tôi đã đề xuất. –

+0

Đề xuất thứ hai hoạt động hoàn hảo, cảm ơn. Tôi thậm chí không nghĩ đến việc kiểm tra '~' – lynks

1

Nói chung, tôi khuyên bạn nên sử dụng ScriptEngine thay vì System.getRuntime(). Exec
Tôi nghĩ điều đó sẽ giúp mọi thứ dễ dàng hơn cho bạn.
Hãy nhớ rằng bạn cần cho JDK 6 trở lên.
Ngoài ra, liên quan đến vấn đề cụ thể của bạn - Tôi thực sự nghĩ rằng vấn đề này nên được cấu hình.
Bạn có thể làm như sau:
A. Có trong .bash_rc hoặc .bash_profile của bạn (cho mỗi người dùng) xác định một đường dẫn đến kịch bản cấu hình
sử dụng:
KHẨU MY_SCRIPT =


B. Tìm hiểu giá trị này từ mã java, sử dụng
String sciprtPath = System.getenv("MY_SCRIPT") để nhận giá trị.
C. Chạy tập lệnh, cách bạn đã làm trong mã của mình, với biến scriptPath hoặc sử dụng tập lệnhEngine.

2

Như đã đề cập, dấu ngã là một mở rộng vỏ cụ thể mà nên được xử lý thủ công bằng cách thay thế nó bằng thư mục chính của người dùng hiện tại (ví dụ: $HOME nếu được xác định).

Bên cạnh những giải pháp đã được đưa ra, bạn cũng có thể xem xét sử dụng commons-iocommons-exec từ Apache Commons dự án:

... 
import org.apache.commons.exec.CommandLine; 
import org.apache.commons.exec.DefaultExecutor; 
import org.apache.commons.exec.Executor; 
import org.apache.commons.io.FileUtils; 
... 
CommandLine cmd = new CommandLine("path/to/shellscript.sh"); 
cmd.addArgument("foo"); 
cmd.addArgument("bar"); 

Executor exec = new DefaultExecutor(); 
exec.setWorkingDirectory(FileUtils.getUserDirectory()); 
exec.execute(cmd); 
... 
Các vấn đề liên quan