我需要執行一個執行另一個Java應用程序的批處理文件。 我不在乎它是否成功執行,我不必捕捉任何錯誤。從Java執行另一個應用程序
可以用ProcessBuilder做到這一點嗎?如果我不捕捉錯誤會有什麼後果?
但是,我的要求只是執行另一個Java應用程序。
我需要執行一個執行另一個Java應用程序的批處理文件。 我不在乎它是否成功執行,我不必捕捉任何錯誤。從Java執行另一個應用程序
可以用ProcessBuilder做到這一點嗎?如果我不捕捉錯誤會有什麼後果?
但是,我的要求只是執行另一個Java應用程序。
我假設你知道如何使用ProcessBuilder
執行該命令。
從Java執行命令總是應該從進程讀取stdout和stderr流。否則,可能會發生緩衝區已滿並且由於寫入其stdout或stderr塊而導致進程無法繼續的情況。
如果你不關心的返回值,你可以只使用Runtime.getRuntime().exec("path.to.your.batch.file");
關於stdout和stderr流從進程中獲得滿的情況如何。 – user234194 2010-08-12 15:10:46
不知道你想要跑什麼,這有點難以分辨。我發現SQL Server的BCP等程序在exec'd和請求stdout和stderr流時不會正確報告錯誤,因此這取決於您的子進程。如果它沒有任何輸出,那麼不用擔心,當過程完成時,stdout和stderr將與您的'Process'對象一起被垃圾回收。 – 2010-08-12 15:15:43
我有一個簡單的問題,如果我一旦執行另一個Java應用程序,我不能做process.destroy。這不會幫助stdout/err充滿,或者我正在談論完全不同的事情。因爲,一旦另一個應用程序啓動,我可以退出我的應用程序。 – user234194 2010-08-12 15:22:11
你可以簡單地使用Runtime.exec()
的Runtime.getRuntime().exec()
做法是相當麻煩的,因爲你很快就會找到答案。
看看Apache Commons Exec項目。它抽象化了許多與使用Runtime.getRuntime().exec()
和ProcessBuilder
API相關的常見問題。
很簡單:
String line = "myCommand.exe";
CommandLine commandLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
int exitValue = executor.execute(commandLine);
這個答案保存了我的生活。謝謝 – Valath 2014-05-04 04:35:32
您可以執行批處理指令,或使用
Runtime.getRuntime().exec(cmd);
而且喲可以等待執行並獲得返回代碼(以檢查其正確執行),此代碼:
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
int exitVal = p.exitValue();
將有更多不同類型的呼叫這裏 http://www.rgagnon.com/javadetails/java-0014.html
的完整說明Process.waitFor()實際上會返回進程的退出代碼,因此您可以將最後兩行合併爲「int.exitVal = p.waitFor();」 – 2011-01-21 07:30:01
是的,它可以使用ProcessBuilder。
的ProcessBuilder例如:
import java.io.*;
import java.util.*;
public class CmdProcessBuilder {
public static void main(String args[])
throws InterruptedException,IOException
{
List<String> command = new ArrayList<String>();
command.add(args[0]);
ProcessBuilder builder = new ProcessBuilder(command);
Map<String, String> environ = builder.environment();
final Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Program terminated!");
}
}
檢查這些例子:
http://www.rgagnon.com/javadetails/java-0014.html
http://www.java-tips.org/java-se-tips/java.util/from-runtime.exec-to-processbuilder.html
線程「主」java.lang.ArrayIndexOutOfBoundsException中的異常:0 \t at RunClByJava.main(RunClByJava.java:94) – 2017-04-26 06:17:46
下面是如何使用ProcessBuilder
執行遠程應用程序的例子。既然你不關心輸入/輸出和/或錯誤,你可以做如下:
List<String> args = new ArrayList<String>();
args.add ("script.bat"); // command name
args.add ("-option"); // optional args added as separate list items
ProcessBuilder pb = new ProcessBuilder (args);
Process p = pb.start();
p.waitFor();
的waitFor()
方法會等到進程已繼續之前結束。此方法返回進程的錯誤代碼,但由於您不關心它,因此我沒有將它放在示例中。
我知道這是一個較老的線程,但我認爲它可能是值得我放入我的實現,因爲我發現此線程試圖做與OP一樣的事情,除了根級別訪問,但沒有真的找到我正在尋找的解決方案。下面的方法創建一個靜態根級別shell,用於僅執行命令而不考慮錯誤檢查或者即使命令成功執行。
我使用它創建的Android手電筒應用程序,可以將LED設置爲不同級別的亮度。通過消除所有錯誤檢查和其他絨毛,我可以讓LED在少至3ms的時間內切換到指定的亮度級別,這爲LightTones(帶光的RingTones)打開了大門。關於應用程序本身的更多細節可以在這裏找到:http://forum.xda-developers.com/showthread.php?t=2659842
以下是整個類。
public class Shell {
private static Shell rootShell = null;
private final Process proc;
private final OutputStreamWriter writer;
private Shell(String cmd) throws IOException {
this.proc = new ProcessBuilder(cmd).redirectErrorStream(true).start();
this.writer = new OutputStreamWriter(this.proc.getOutputStream(), "UTF-8");
}
public void cmd(String command) {
try {
writer.write(command+'\n');
writer.flush();
} catch (IOException e) { }
}
public void close() {
try {
if (writer != null) { writer.close();
if(proc != null) { proc.destroy(); }
}
} catch (IOException ignore) {}
}
public static void exec(String command) { Shell.get().cmd(command); }
public static Shell get() {
if (Shell.rootShell == null) {
while (Shell.rootShell == null) {
try { Shell.rootShell = new Shell("su"); //Open with Root Privileges
} catch (IOException e) { }
}
}
return Shell.rootShell;
}
}
然後隨時隨地在我的應用程序運行一個命令,例如改變LED的亮度,我只要致電:
Shell.exec("echo " + bt.getLevel() + " > "+ flashfile);
下面代碼片段寫入編譯和使用的ProcessBuilder運行外部JAVA程序,我們也可以運行任何外部程序。確保必須在OS環境中設置JAVA_HOME。看more
package com.itexpert.exam;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class JavaProcessBuilder {
/**
* Provide absolute JAVA file path
*/
private static final String JAVA_FILE_LOCATION = "D:\\Test.java";
public static void main(String args[]) throws IOException{
String command[] = {"javac",JAVA_FILE_LOCATION};
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
/**
* Check if any errors or compilation errors encounter then print on Console.
*/
if(process.getErrorStream().read() != -1){
print("Compilation Errors",process.getErrorStream());
}
/**
* Check if javac process execute successfully or Not
* 0 - successful
*/
if(process.exitValue() == 0){
process = new ProcessBuilder(new String[]{"java","-cp","d:\\","Test"}).start();
/** Check if RuntimeException or Errors encounter during execution then print errors on console
* Otherwise print Output
*/
if(process.getErrorStream().read() != -1){
print("Errors ",process.getErrorStream());
}
else{
print("Output ",process.getInputStream());
}
}
}
private static void print(String status,InputStream input) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(input));
System.out.println("************* "+status+"***********************");
String line = null;
while((line = in.readLine()) != null){
System.out.println(line);
}
in.close();
}
}
我能看到有比Apache的百科全書EXEC庫更好庫。 您可以使用Java Secure Shell(JSch)執行您的作業。
我有同樣的問題。我用JSch來解決這個問題。 Apache commons在不同服務器上運行命令時遇到了一些問題。 Plus JSch給了我結果和錯誤InputStreams。我發現它更優雅。樣品溶液可以在這裏找到:http://wiki.jsch.org/index.php?Manual%2FExamples%2FJschExecExample
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.commons.exec.*;
import com.jcraft.*;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.ChannelExec;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
public class exec_linux_cmd {
public HashMap<String,List<String>> exec_cmd (
String USERNAME,
String PASSWORD,
String host,
int port,
String cmd)
{
List<String> result = new ArrayList<String>();
List<String> errors = new ArrayList<String>();
HashMap<String,List<String>> result_map = new HashMap<String,List<String>>();
//String line = "echo `eval hostname`";
try{
JSch jsch = new JSch();
/*
* Open a new session, with your username, host and port
* Set the password and call connect.
* session.connect() opens a new connection to remote SSH server.
* Once the connection is established, you can initiate a new channel.
* this channel is needed to connect and remotely execute the program
*/
Session session = jsch.getSession(USERNAME, host, port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(PASSWORD);
session.connect();
//create the excution channel over the session
ChannelExec channelExec = (ChannelExec)session.openChannel("exec");
// Gets an InputStream for this channel. All data arriving in as messages from the remote side can be read from this stream.
InputStream in = channelExec.getInputStream();
InputStream err = channelExec.getErrStream();
// Set the command that you want to execute
// In our case its the remote shell script
channelExec.setCommand(cmd);
//Execute the command
channelExec.connect();
// read the results stream
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
// read the errors stream. This will be null if no error occured
BufferedReader err_reader = new BufferedReader(new InputStreamReader(err));
String line;
//Read each line from the buffered reader and add it to result list
// You can also simple print the result here
while ((line = reader.readLine()) != null)
{
result.add(line);
}
while ((line = err_reader.readLine()) != null)
{
errors.add(line);
}
//retrieve the exit status of the remote command corresponding to this channel
int exitStatus = channelExec.getExitStatus();
System.out.println(exitStatus);
//Safely disconnect channel and disconnect session. If not done then it may cause resource leak
channelExec.disconnect();
session.disconnect();
System.out.println(exitStatus);
result_map.put("result", result);
result_map.put("error", errors);
if(exitStatus < 0){
System.out.println("Done--> " + exitStatus);
System.out.println(Arrays.asList(result_map));
//return errors;
}
else if(exitStatus > 0){
System.out.println("Done -->" + exitStatus);
System.out.println(Arrays.asList(result_map));
//return errors;
}
else{
System.out.println("Done!");
System.out.println(Arrays.asList(result_map));
//return result;
}
}
catch (Exception e)
{
System.out.print(e);
}
return result_map;
}
//CommandLine commandLine = CommandLine.parse(cmd);
//DefaultExecutor executor = new DefaultExecutor();
//executor.setExitValue(1);
//int exitValue = executor.execute(commandLine);
public static void main(String[] args)
{
//String line = args[0];
final String USERNAME ="abc"; // username for remote host
final String PASSWORD ="abc"; // password of the remote host
final String host = "3.98.22.10"; // remote host address
final int port=22; // remote host port
HashMap<String,List<String>> result = new HashMap<String,List<String>>();
//String cmd = "echo `eval hostname`"; // command to execute on remote host
exec_linux_cmd ex = new exec_linux_cmd();
result = ex.exec_cmd(USERNAME, PASSWORD , host, port, cmd);
System.out.println("Result ---> " + result.get("result"));
System.out.println("Error Msg ---> " +result.get("error"));
//System.out.println(Arrays.asList(result));
/*
for (int i =0; i < result.get("result").size();i++)
{
System.out.println(result.get("result").get(i));
}
*/
}
}
編輯1:爲了找到你的進程(如果它是一個長期運行的一個)是在Unix上運行,使用ps -aux | grep java
。進程ID應與您正在執行的unix命令一起列出。
有什麼辦法可以啓動另一個應用程序,並忽略進程中的stdout和stderr流。 – user234194 2010-08-12 15:10:05
也許你會創建一個'bat'文件,將執行命令的輸出重定向到「dev-null」。 – Mot 2010-08-13 06:27:18