2012-12-24 53 views
6

tôi đã chạy một kịch bản Perl thay thế một chuỗi với nhau:Perl script chạy trong terminal nhưng không chạy khi gọi từ chương trình Java

perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt 

Khi tôi chạy lệnh này từ thiết bị đầu cuối nó cũng thay thế tất cả các sự xuất hiện của str1 trong tệp đã cho tới str2. Khi tôi chạy này từ java nó truy cập các tập tin nhưng không có sự thay thế xảy ra:

Runtime.getRuntime().exec("perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt"); 
  • Tôi chắc chắn rằng nó truy cập các tập tin (file dường như được chỉnh sửa trong gedit (Yêu cầu tải lại)).
  • tôi đã cố gắng Java ProcessBuilder lớp nhưng kết quả tương tự xảy ra.
  • Khi tôi sử dụng Runtime.exec() hoặc ProcessBuilder với các lệnh khác (như gedit newFile.txt), chúng hoạt động tốt.
  • Trớ trêu thay, tôi in lệnh perl trên từ java và lấy dán vào thiết bị đầu cuối và thay thế hoạt động được thực hiện!
  • Không có ngoại lệ hoặc lỗi nào khi sử dụng các lệnh đó. (Tôi đã sử dụng thử và nắm bắt để đảm bảo điều này).
  • Tôi cũng sử dụng /usr/bin/perl thay vì perl trong cmd để đảm bảo cmd perl được thực thi.

Vậy điều gì làm bạn nghĩ rằng vấn đề là gì?

EDIT:

Tôi giải quyết vấn đề này bằng cách chỉ xóa dấu ngoặc kép khỏi lệnh trong java. Nhờ @ikegami để được trợ giúp. Vì vậy, phiên bản làm việc là:

perl -pi.back -e s/str1/str2/g; path/to/file1.txt 

thay vì

perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt 
+0

'exec()' trả về cho bạn một 'Process', nó có phương thức' getInputStream() 'và' getErrorStream() 'trả về cho bạn bất kỳ đầu ra nào mà quá trình tạo ra. Xem những gì quá trình này kết quả đầu ra. –

+1

Tùy thuộc vào hệ điều hành, chương trình Java của bạn có thể không có đường dẫn đến Perl. Bạn sẽ cần phải đặt đường dẫn đầy đủ vào nhị phân Perl. Đó không phải là cách duy nhất để làm điều đó, mà là một trong những cách đơn giản nhất. – octopusgrabbus

+0

@DenisTulskiy Tôi đã làm điều này. Chúng không có gì. – a90

Trả lời

5

exec sử dụng StringTokenizer để phân tích lệnh, mà dường như chỉ chia tách vào khoảng trắng.

Đưa ví dụ lệnh vỏ sau (tương tự nhưng khác với bạn):

perl -pi.back -e 's/a/b/g; s/c/d/g;' path/to/file1.txt 

Đối với nó, StringTokenizer sản xuất lệnh sau và lập luận:

  • perl (lệnh)
  • -pi.back
  • -e
  • 's/a/b/g;
  • s/c/d/g;'
  • path/to/file1.txt

Đó là hoàn toàn sai.Các lệnh và đối số nên

  • perl (lệnh)
  • -pi.back
  • -e
  • s/a/b/g; s/c/d/g; (Lưu ý việc thiếu dấu ngoặc kép.)
  • path/to/file1.txt

Bạn có thể vượt qua những ở trên đến exec(String[] cmdarray). Hoặc nếu bạn không có tùy chọn phân tích cú pháp lệnh, bạn thực sự có thể gọi một vỏ để phân tích nó cho bạn bằng cách sau đây để exec(String[] cmdarray):

  • sh (lệnh)
  • -c
  • perl -pi.back -e 's/a/b/g; s/c/d/g;' path/to/file1.txt
+0

Bạn nên thử 'perl -le'print cho @ARGV 'perl -pi.back -e' s/str1/str2/g; ' path/to/file1.txt' và xem những gì thực sự được chuyển đến Perl bởi trình bao. Bạn cũng nên thử nó mà không có không gian (không cần thiết) sau '-e'. – ikegami

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