Java—如何检测bash是否已返回?

Java—如何检测bash是否已返回?,java,linux,bash,shell,process,Java,Linux,Bash,Shell,Process,我正在编写一个程序,我想在后台启动一个shell,并发送和接收输入和输出。我已经成功地做到了这一点,并且可以成功地读取和写入此进程。这就是我遇到麻烦的地方 我希望在ShellManager(参见下面的代码)中有一个方法,它可以等待进程所做的任何事情完成/失败,并将输入返回给用户 例如,如果我发送tar xzf某物,而.tar.gz,它将在, 我可以在输出中看到它是如何花费时间的,然后重复这一点: ]0;~ [32mMe@MyComputer [33m~[0m 我已经尝试阻塞线程,直到]0~时,

我正在编写一个程序,我想在后台启动一个shell,并发送和接收输入和输出。我已经成功地做到了这一点,并且可以成功地读取和写入此进程。这就是我遇到麻烦的地方

我希望在
ShellManager
(参见下面的代码)中有一个方法,它可以等待进程所做的任何事情完成/失败,并将输入返回给用户

例如,如果我发送
tar xzf某物,而.tar.gz
,它将在, 我可以在输出中看到它是如何花费时间的,然后重复这一点:

]0;~
[32mMe@MyComputer [33m~[0m
我已经尝试阻塞线程,直到
]0~时,此操作无效。(从未返回)

我还尝试了
\u001B
,同样的问题:(

我不确定符号是什么,也找不到太多关于如何检测进程何时返回的信息

这是我的密码:

package buildSystem.shell;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import base.TermConstants;

public class ShellManager {
    private InputStream termOut;
    private OutputStream termIn;

    private ProcessBuilder build;
    private Process main;

    BufferedReader reader;
    BufferedWriter writer;

    public ShellManager() {
        build = new ProcessBuilder(TermConstants.getShellLocation());
        build.redirectErrorStream(true);    
    }

    public void start() throws IOException {
        try {
            main = build.start();
            termOut = main.getInputStream();
            termIn = main.getOutputStream();
            reader = new BufferedReader (new InputStreamReader(termOut));
            writer = new BufferedWriter(new OutputStreamWriter(termIn));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void writeLine(String s) throws IOException {
        writer.write(s);
        writer.newLine();
        writer.flush();
    }

    public String readNextLine() throws IOException {
        return reader.readLine();
    }

    public void end() {
        try {
            writeLine("exit\n");
            main.waitFor();
            termOut.close();
            termIn.close();
            reader.close();
            writer.close();
        } catch (IOException | InterruptedException e) {
            kill();
        }
    }

    public void kill() {
        main.destroyForcibly();
        try {
            termOut.close();
            termIn.close();
            reader.close();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

/*THE PART I AM HAVING TROUBLE WITH:*/

    public void waitForReturn() {
        try {
            while(reader.readLine() != "\u001B") {}
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
基本上,我需要一种可靠的方法来检测程序何时从bash shell退出。bash进程仍将运行,但从该bash实例运行的程序将返回。因此,我无法使用
process.waitFor()

我尝试等待
]0;~
,然后等待
[32mMe@MyComputer[33m~[0m
,它一直工作到一个带有错误代码的tar退出,在这种情况下,这两行将被颠倒。我不确定如何继续,因为检测bash已返回给用户应该是一项相对简单的任务


谢谢您的帮助!

我相信您需要调用Process.waitFor()方法。 所以你需要一些类似的东西:

Process p = build.start();
p.waitFor()
如果您试图模拟bash shell,则允许输入命令、执行和处理输出而不终止。有一个开源项目可能是有关如何执行此操作的代码的良好参考。它在Git上可用。请查看纯Java仿真器

考虑到模拟bash,我还发现这个示例也与之相关


它确实显示了如何提取正在执行的进程的输出,并将该数据作为输入传递到另一个Java进程中。这应该很有帮助。

如果这代表了您一直试图匹配输出的方式,那就是您的问题:

while(reader.readLine() != "\u001B") {}
除特殊情况外,您必须在
String
实例上使用
equals()
方法:

while (true) {
  String line = reader.readLine();
  if ((line == null) || "\u001B".equals(line))
    break;
}

我不知道为什么进程退出时会出现
ESC
和换行符。

您好,谢谢您的回答!不幸的是,这不起作用,因为在bash运行时,进程正在运行,即使它已返回给用户。但是,如果shell在运行命令后退出,这将起作用,但这不是我需要的。谢谢不管怎样,谢谢你的回答!@TooManyPolygons你的问题是如何判断bash何时回来。如果这不是你真正的意思,请修正你的问题。@erickson我不确定你的意思。它特别用粗体字说明我不能使用
process.waitFor()
。(不是在发布答案的时候,而是在你发布评论之前)。为什么我的问题需要“修正”?它非常具体。我不明白为什么在我回复答案两个月后出现并告诉我需要修正它会有任何帮助。所以,不。我的问题不是“你怎么知道bash何时回来?”,它更具体。如果你不喜欢它,请至少试着写一个原因。你真的读过吗?在我的答案发布后,你更新了关于waitfor();)@pczeus是的,我读过:)不过,我很感激您的回答,即使它不是我所需要的。您必须在调用
waitFor()之前关闭流
.Otherwise你有一个死锁。这很有效。老实说,我不知道为什么我没有看到这一点,因为我通常不会犯那个错误。非常感谢!而且,我检查了
esc
,只是因为我尝试了我能想到的所有其他方法。我完全错过了实际问题,所以再次感谢你找到它。我仍然不敢相信就这么简单。