Saya menggunakan runtime untuk menjalankan perintah command prompt dari program Java saya. Namun, saya tidak tahu bagaimana saya bisa mendapatkan output yang dikembalikan oleh perintah.
Ini kode saya:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send" , argument};
Process proc = rt.exec(commands);
Saya mencoba melakukan System.out.println(proc);
tetapi itu tidak mengembalikan apa pun. Eksekusi perintah itu harus mengembalikan dua angka yang dipisahkan oleh tanda titik koma. Bagaimana saya bisa mendapatkan ini dalam variabel untuk dicetak?
Ini kode yang saya gunakan sekarang:
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
InputStream stdIn = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdIn);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<OUTPUT>");
while ((line = br.readLine()) != null)
System.out.println(line);
System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
Tapi saya tidak mendapatkan apa pun sebagai output saya, tetapi ketika saya menjalankan sendiri perintah itu berfungsi dengan baik.
pwd && ls
tidak hanya mengeksekusi satu file, ketika Anda melakukannya dalam sebuah shell, ia mengeksekusi file/bin/pwd
dan/bin/ls
executable. Jika Anda ingin melakukan hal-hal seperti itu dalam java Anda harus melakukan sesuatu seperti{"/bin/bash","-c", "pwd && ls"}
. Anda mungkin tidak memiliki pertanyaan lagi tetapi orang lain mungkin jadi saya pikir saya akan menjawabnya.stdout
danstderr
output terbatas . Jika Anda tidak mendengarkannya secara bersamaan, salah satunya akan terisi saat Anda membaca yang lain. Program yang sedang Anda dengarkan kemudian akan memblokir mencoba menulis ke buffer yang diisi, sementara di sisi lain program Anda akan memblokir mencoba membaca dari buffer yang tidak akan pernah kembaliEOF
. Anda harus membaca dari kedua aliran secara bersamaan.Cara yang lebih cepat adalah ini:
Yang pada dasarnya adalah versi kental ini:
Saya tahu pertanyaan ini sudah lama tetapi saya memposting jawaban ini karena saya pikir ini mungkin lebih cepat.
sumber
\A
dalam regex berarti awal dari string dan saya harus lolos dari tebasan.Selain menggunakan
ProcessBuilder
seperti yang disarankan Senthil, pastikan untuk membaca dan mengimplementasikan semua rekomendasi When Runtime.exec () tidak akan .sumber
ProcessBuilder
seperti yang sekarang direkomendasikan dua kali. Menggunakan aProcessBuilder
, dimungkinkan untuk menggabungkan aliran output & kesalahan untuk membuatnya lebih mudah untuk mengkonsumsi keduanya sekaligus.Jika penggunaan sudah memiliki Apache commons-io tersedia di classpath, Anda dapat menggunakan:
sumber
Kita juga dapat menggunakan stream untuk mendapatkan output perintah:
sumber
@Senthil dan @Arend jawaban ( https://stackoverflow.com/a/5711150/2268559 ) disebutkan
ProcessBuilder
. Berikut adalah contoh menggunakanProcessBuilder
dengan menentukan variabel lingkungan dan folder yang berfungsi untuk perintah:sumber
Pada saat penulisan ini, semua jawaban lain yang menyertakan kode dapat mengakibatkan kebuntuan.
Proses memiliki buffer terbatas untuk
stdout
danstderr
output . Jika Anda tidak mendengarkannya secara bersamaan, salah satunya akan terisi saat Anda mencoba membaca yang lain. Misalnya, Anda bisa menunggu untuk membaca daristdout
saat proses menunggu untuk menulisstderr
. Anda tidak dapat membaca daristdout
buffer karena kosong dan proses tidak dapat menulis kestderr
buffer karena penuh. Anda masing-masing saling menunggu selamanya.Berikut adalah cara yang mungkin untuk membaca output dari suatu proses tanpa risiko kebuntuan:
Kuncinya adalah menggunakan
ProcessBuilder.redirectErrorStream(true)
yang akan mengarahkan ulangstderr
kestdout
aliran. Ini memungkinkan Anda membaca aliran tunggal tanpa harus bergantian antarastdout
danstderr
. Jika Anda ingin menerapkan ini secara manual, Anda harus menggunakan stream di dua utas berbeda untuk memastikan Anda tidak pernah memblokir.sumber
Jika Anda menulis di Kotlin, Anda dapat menggunakan:
sumber
Diadaptasi dari jawaban sebelumnya:
sumber
Hampir sama dengan cuplikan lainnya di laman ini tetapi hanya mengatur berbagai hal di atas suatu fungsi , ini dia ...
Fungsi kelas:
sumber
Coba baca
InputStream
runtime:Anda mungkin juga perlu membaca aliran kesalahan (
proc.getErrorStream()
) jika proses mencetak keluaran kesalahan. Anda dapat mengalihkan aliran kesalahan ke aliran input jika Anda menggunakanProcessBuilder
.sumber