用java执行复杂流程命令行

用java执行复杂流程命令行,java,linux,command-line,process,Java,Linux,Command Line,Process,我尝试使用ProcessBuilder从java类执行命令行流程。 成功的执行实际上会在eclipse中打开另一个终端。 *这就像:* 进程-->打开-->子进程 其余所有命令都必须在子流程中执行 有人帮助我了解如何触发子流程,并在完成后退出该子流程 注意: 给定的命令只是一个示例,这个问题与“jdbc”无关,它只涉及流程和子流程 我无法测试您正在执行的确切命令,但问题可能是它们实际上没有停止执行,这就是您的主进程没有停止的原因 解决办法是: 用于检查这些命令是否仍在执行,并在超时后终止这些进

我尝试使用ProcessBuilder从java类执行命令行流程。 成功的执行实际上会在eclipse中打开另一个终端。 *这就像:* 进程-->打开-->子进程 其余所有命令都必须在子流程中执行

有人帮助我了解如何触发子流程,并在完成后退出该子流程

注意:

给定的命令只是一个示例,这个问题与“jdbc”无关,它只涉及流程和子流程


我无法测试您正在执行的确切命令,但问题可能是它们实际上没有停止执行,这就是您的主进程没有停止的原因

解决办法是:

用于检查这些命令是否仍在执行,并在超时后终止这些进程。 方法使它们在超时后终止。然后,您可以使用方法检查进程是否正常退出。
看看您的示例,看起来您正在尝试在mysql上运行sql命令

首先,如果您确实想使用msqyl命令行命令执行此操作,那么您需要将其输入/输出重定向到javainputstream/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;");
然后,驱动程序将演示如何向该命令行工具发送命令:

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();
    }
}

您误解了如何调用操作系统进程

每个进程由程序名(如notepad.exe或java.exe)和零个或多个命令行参数组成

ProcessBuilder能够一次运行一个命令。构成其命令的字符串列表不是单独的命令;它们表示程序名及其各个命令行参数

因此,要运行mysql,您需要分离命令行参数:

ProcessBuilder pb = new ProcessBuilder("mysql", "-u", "root", "-p", password);
在下一行中,选择*from employee;,不是系统命令,也不是子进程。这是一个mysql命令——一个只有mysql才能理解的指令。您可能可以将其写入mysql进程的标准输入,因为mysql碰巧通过标准输入接受命令:

try (Writer writer = new OutputStreamWriter(process.getOutputStream())) {
    write.write("select * from employee;");
}
然而,并非所有程序都通过其标准输入接受命令


正如您所知道的,mysql并不是一个很好的外部进程候选者。读取和解析输出比乍一看要困难得多。JDBC将是更好的选择。您似乎知道这一点,但我提到这一点是为了其他读者的利益。

它应该退出主进程,向我们展示代码。使用我尝试执行的代码编辑,它将仅启动主进程,如何在此进程之上启动子进程。我已使用可执行命令更新了代码,在这种情况下会发生什么,因为mysql命令行将打开msql命令行子进程,所以我们必须执行select*查询。。如何做到这一点?我明白你的意思,mysql只是我在这里给出的一个示例,任何人都可以在命令行中执行它。我正在寻找一个真正的命令行脚本的执行,它没有任何jdbc类型的库。。谢谢你,伙计。。我将编辑我的问题以反映视图。我为第一个解决方案添加了一个示例代码,它可能会满足您的需要。它根本不会触发select*查询。。!我现在添加了一个完整的java工作示例。希望它能帮上忙这是个好主意,除了把它写进文件。。我需要字符串形式的结果。。干杯谢谢matewell用外行的语言解释,很好。。然而,这个答案看起来很相似。这种需求与myslq/jdbc无关。下一步涉及到一个子流程,我无法解释得比这个更好。因此,假设查询是另一个子流程。具有挑战性的任务是解析输出并仅指出结果值。如何使外部进程生成自己的子进程完全取决于外部进程是什么。没有通用的方法可以让一个进程启动另一个进程。
ProcessBuilder pb = new ProcessBuilder("mysql", "-u", "root", "-p", password);
try (Writer writer = new OutputStreamWriter(process.getOutputStream())) {
    write.write("select * from employee;");
}