【问题标题】:Groovy - Shell Scripting - Unable to Communicate back n forthGroovy - Shell 脚本 - 无法来回通信
【发布时间】:2023-03-06 01:38:01
【问题描述】:

我是 Groovy 的新手,我正在尝试编写一个 shell 脚本来让我自动执行命令行任务。

这里是手动方式。 我打开终端,使用一个命令,它不会立即响应,但在一段时间后,然后该命令会问几个问题,我回答 y/n 等,然后我得到最终结果。

现在我想编写一个 groovy shell 脚本,让我使用 ProcessBuilder,然后发送一个命令,获取输出,然后根据输出编写第二个命令并重复此过程,直到过程完成。

我尝试编写以下脚本,但发生的情况是我能够触发第一个命令,但它不会等待我提供输入并继续。

请告知我应该在我的代码中进行哪些更改以等待它在我发送 first_command 之后从我的代码中获取输入。

#!/usr/bin/env groovy

String workingDir = System.console().readLine 'Working Directory?';
workingDir = workingDir.trim();

if (!workingDir?.trim()) {
  workingDir = "/Volumes/BOOTCAMP/Automation/test";
}

println "Your working directory is $workingDir";

Boolean isDone = false;
Boolean canMove = false;

ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash");
processBuilder.directory(new File(workingDir));
processBuilder.redirectErrorStream(true);

Process proc = processBuilder.start();
Scanner scannr = new Scanner(proc.getInputStream());

new Thread() {
    public void run() {
      while(true){
        while (scannr.hasNextLine()){
          println scannr.nextLine();
        }
        if(isDone){
          break; 
        }
      }
    }
}.start();

PrintWriter writer = new PrintWriter(proc.getOutputStream());
new Thread() {
    public void run() {
        while (isDone == false){
          if(canMove == false){
            canMove = true;

            // Write a few commands to the program.
            writer.println("first_command");
            writer.flush();
          }
        }

        if(isDone){
          writer.close();
        }
    }
}.start();

【问题讨论】:

    标签: java bash macos shell groovy


    【解决方案1】:

    java.lang.Process 类的 groovy 扩展中有很多 waitXXX 函数

    http://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Process.html

    流程输出不大时的示例实现:

    Process p = "cmd /c dir c:\\".execute() //you can use BrocessBuilder here
    def txt = p.with{
        def output = new StringWriter()
        def error = new StringWriter()
        //wait for process ended and catch stderr and stdout 
        it.waitForProcessOutput(output, error)
        //check there is no error
        assert error.toString().size()==0: "$error"
        //assert it.exitValue()==0 //we can do check with error code
        //return stdout from closure 
        return output.toString()
    }
    

    【讨论】:

    • 感谢您的回复,我使用 ProcessBuilder 是因为我“假设” UNLIKE "command".execute,ProcessBuilder 可用于在同一个启动的进程中运行多个条件命令。这意味着使用 Execute 不是我想要的,waitForProecessOutput 文档说“最后,输入、输出和错误流都关闭了。”。我不希望它们关闭,我想像你在 output.ToString() 中那样读取输出,然后根据输出将第二个命令发送到同一个打开/启动的进程。我能做到吗?
    • 无论如何都会产生新的进程。进程生成后,您可以将前一个进程的输出写入其输入流。例如检查leftShift 方法:nextProc << prevOutput
    • 恐怕这不能解决我的问题,因为下一个命令不是命令而是对第一个命令的回答,例如,当我使用命令启动进程时,该命令会像向导一样问几个问题是 否 然后链接到网站,然后下载该链接,最后对其进行处理并返回结果。这意味着我需要“期望”框架之类的功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 2016-06-15
    • 2020-11-27
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多