簡體   English   中英

用Java執行復雜的進程命令行

[英]Executing complex process commandline with java

我試圖使用ProcessBuilder從Java類執行命令行過程。
成功執行實際上打開了我日食中的另一個終端。
*這就像:*
流程---->打開---->子流程
所有其他命令必須在子進程中執行

有人幫助我了解如何觸發子流程 ,一旦完成退出該流程的操作。

List commands = new ArrayList<String>();
    commands.add("mysql -u root -p ********");
    commands.add("select * from employee;");
    System.out.println(commands);
ProcessBuilder pb = new ProcessBuilder(commands);
Process process = pb.start();


注意:

給定命令僅作為示例,問題與“ jdbc”無關,它與流程和子流程有關。

您誤解了如何調用操作系統進程。

每個進程都由程序名稱(例如notepad.exejava.exe )以及零個或多個命令行參數組成。

ProcessBuilder能夠一次運行一個命令 構成其命令的字符串列表不是單獨的命令; 它們代表程序名稱及其單獨的命令行參數。

因此,要運行mysql,您需要將命令行參數分開:

ProcessBuilder pb = new ProcessBuilder("mysql", "-u", "root", "-p", password);

您的下一行, select * from employee; ,不是系統命令,也不是子進程。 這是一個mysql命令-僅mysql可以理解的指令。 您可能可以將其寫入mysql進程的標准輸入 ,因為mysql恰好通過標准輸入接受命令:

try (Writer writer = new OutputStreamWriter(process.getOutputStream())) {
    write.write("select * from employee;");
}

但是,並非所有程序都通過其標准輸入接受命令。

如您所知,mysql並不是外部進程的理想選擇。 讀取和解析輸出將比乍一看要困難得多。 JDBC將是更好的選擇。 (您似乎知道這一點,但我為了其他讀者的利益而提到了它。)

我無法測試您正在執行的確切命令,但是問題可能是它們實際上並沒有停止執行,這就是為什么您的主進程沒有停止的原因。

解決方法是:

  1. 使用isAlive()檢查這些命令是否仍在執行(並在超時后終止這些進程)。
  2. 使用waitFor(long timeout, TimeUnit unit)方法使它們在超時后終止。 然后,您可以使用exitValue()方法檢查進程是否正常退出。

查看您的示例,似乎您正在嘗試在mysql上運行sql命令。

首先,如果您確實想使用msqyl命令行命令執行此操作,則要將其輸入/輸出重定向到java InputStream / OutputStream,然后將您的SQL請求發送到mysql進程輸入。 您可能會遵循以下示例:

    List<String> command = new ArrayList<>();
    command.add("mysql -u root -p ********");
    ProcessBuilder pb = new ProcessBuilder(command);
    Process process = pb.start();
    PrintStream commandIn = new PrintStream(process.getOutputStream());
    commandIn.println("select * from employee;");

第二,在mysql實例上運行SQL命令的最佳方法是使用JDBC,而不是mysql命令行工具。 尋找大量的JDBC教程。

這是一個更完整(且有效)的示例。 看一下這個“命令行工具”:

public class TestCmd {

    public static void main(String[] args) throws IOException
    {
        System.out.println("Started. args[0]=" + args[0]);

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        for(;;)
        {
            String line = in.readLine();
            if (line == null) break;
            System.out.println("echo:" + line);
        }
    }
}

然后,“驅動程序”程序女巫演示如何將命令發送到此命令行工具:

public class TestDriver {

    final static String JAVA_EXE = "C:\\...\\java.exe";
    final static String CLASS_BASEPATH = "C:\\...\\java\\bin";

    public static void main(String[] args) throws Exception
    {
        List<String> command = new ArrayList<>();
        command.add(JAVA_EXE.toString());
        command.add("-classpath");
        command.add(CLASS_BASEPATH);
        command.add("TestCmd");
        command.add("Parameter");
        ProcessBuilder pb = new ProcessBuilder(command);
        pb.redirectOutput(new File("c:\\temp\\out.txt"));

        Process process = pb.start();
        PrintStream commandIn = new PrintStream(process.getOutputStream());

        commandIn.println("first input line");
        commandIn.flush();
        commandIn.println("second input line");
        commandIn.flush();

        // give some time to the sub process to finish writing its output
        Thread.sleep(100);

        process.destroy();
    }
}

正如預期的那樣,在輸出“ out.txt”中,您將獲得:

Started. args[0]=Parameter
echo:first input line
echo:second input line

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM