我下面有以下代码示例。你可以在其中输入bash shell
的命令,即echo test
回显结果。但是,先读后。其他输出流不起作用?
为什么会这样或我做错了什么?我的最终目标是创建一个线程计划任务,该任务定期执行对/ bash的命令,因此OutputStreamand InputStream
必须一前一后工作,而不能停止工作。我也一直在经历错误的java.io.IOException: Broken pipe
任何想法?
谢谢。
String line;
Scanner scan = new Scanner(System.in);
Process process = Runtime.getRuntime ().exec ("/bin/bash");
OutputStream stdin = process.getOutputStream ();
InputStream stderr = process.getErrorStream ();
InputStream stdout = process.getInputStream ();
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
String input = scan.nextLine();
input += "\n";
writer.write(input);
writer.flush();
input = scan.nextLine();
input += "\n";
writer.write(input);
writer.flush();
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
input = scan.nextLine();
input += "\n";
writer.write(input);
writer.close();
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
首先,我建议更换生产线
Process process = Runtime.getRuntime ().exec ("/bin/bash");
与线
ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.redirectErrorStream(true);
Process process = builder.start();
ProcessBuilder是Java 5中的新增功能,它使运行外部进程更加容易。在我看来,它最大的改进Runtime.getRuntime().exec()
是它允许你将子进程的标准错误重定向到其标准输出中。这意味着你只有一个人InputStream
可以阅读。在此之前,你需要有两个单独的线程,一个从中stdout读取,另一个从中读取stderr
,以避免在标准输出缓冲区为空(导致子进程挂起)时填充标准错误缓冲区,反之亦然。
接下来,循环(其中有两个循环)
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
仅当reader从流程的标准输出读取的,返回文件末尾时退出。这仅在bash进程退出时发生。如果当前碰巧不再有该过程的输出,它将不会返回文件结尾。相反,它将等待流程的下一行输出,直到有下一行才返回。
由于你要在到达此html" target="_blank">循环之前向流程发送两行输入,因此,如果在这两行输入之后流程尚未退出,则这两个循环中的第一个将挂起。它会坐在那里等待另一行被读取,但是永远不会再有另一行可以读取。
我编译了你的源代码(目前我在Windows上,所以我将其替换/bin/bash为cmd.exe,但是原理应该相同),我发现:
echo test
然后输入exit
,则该程序将退出第一个循环,因为该cmd.exe
进程已退出。然后,程序要求输入另一行(将被忽略),由于子进程已经退出,因此直接跳过了第二个循环,然后退出自身。exit
然后输入,则会echo test
收到IOException
,抱怨管道被关闭。这是可以预期的-输入的第一行导致进程退出,并且无处发送第二行。我获取了你的代码,并writer
使用以下循环替换了分配给该行的所有内容:
while (scan.hasNext()) {
String input = scan.nextLine();
if (input.trim().equals("exit")) {
// Putting 'exit' amongst the echo --EOF--s below doesn't work.
writer.write("exit\n");
} else {
writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
}
writer.flush();
line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
System.out.println ("Stdout: " + line);
line = reader.readLine();
}
if (line == null) {
break;
}
}
完成此操作后,我可以可靠地运行一些命令,并将每个命令的输出分别返回给我。
echo --EOF--
发送到shell的那一行中的两个命令可以确保–EOF–即使在命令出错的情况下也可以终止命令的输出。
当然,这种方法有其局限性。这些限制包括:
--EOF--
。bash
报告语法错误,如果输入的文本不匹配,则会退出)。如果你要考虑的是计划任务中要执行的任务,那么这些要点可能对你而言并不重要,因为这些任务将仅限于一个命令或一小部分命令,这些命令或行为永远不会以这种病理方式表现。
编辑:在Linux上运行此命令后,改善退出处理和其他较小更改。
问题内容: 我正在尝试创建一种控制台/终端,允许用户输入一个字符串,然后将其编入进程并打印出结果。就像普通的控制台一样。但是我在管理输入/输出流时遇到了麻烦。我已经研究了这个线程,但是可悲的是,该解决方案不适用于我的问题。 与标准命令(例如“ ipconfig”和“ cmd.exe”)一起,如果脚本要求输入,我还需要能够运行脚本并使用相同的输入流传递一些参数。 例如,在运行脚本“ python p
本小节将会介绍基本输入输出的 Java 标准类,通过本小节的学习,你将了解到什么是输入和输入,什么是流;输入输出流的应用场景,File类的使用,什么是文件,Java 提供的输入输出流相关 API 等内容。 1. 什么是输入和输出(I / O) 1.1 基本概念 输入/输出这个概念,对于计算机相关专业的同学并不陌生,在计算中,输入/输出(Input / Output,缩写为 I / O)是信息处理系
我想用java代码调用一个外部程序,然后Google告诉我Runtime或ProcessBuilder可以帮助我完成这项工作。我试过了,结果发现java程序无法退出,这意味着子进程和父进程都将永远等待。它们要么挂起,要么陷入僵局。 有人告诉我原因是子进程的缓存太小了。当它试图将数据返回给父进程时,但是父进程没有及时读取它,然后他们两个都挂起了。所以他们建议我叉一个线程来负责读取子进程的缓存数据。我
本文向大家介绍JAVA输出流与输入流代码实例,包括了JAVA输出流与输入流代码实例的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了JAVA输出流与输入流代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 输出流 编程入门的第一个程序,输出一串字符串 输入流 输入流需要引用包的概念,包里面存放的是类。输入流需要实例化InputStr
主要内容:C++输入流和输出流本教程一开始就提到,C++ 又可以称为“带类的 C”,即可以理解为 C++ 是 C 语言的基础上增加了面向对象(类和对象)。在此基础上,学过 C 语言的读者应该知道,它有一整套完成数据读写(I/O)的解决方案: 使用 scanf()、gets() 等函数从键盘读取数据,使用 printf()、puts() 等函数向屏幕上输出数据; 使用 fscanf()、fgets() 等函数读取文件中的数据,使
问题内容: 有没有人有创建Java中的管道对象,任何好的建议 是 从Java既是一个InputStream和和OutputStream没有多重继承和两个流是抽象类,而不是接口? 基本需求是有一个可以传递给需要InputStream或OutputStream的对象的对象,该对象需要将一个线程的输出传递给另一个线程的输入。 问题答案: 看来这个问题的重点已被遗漏。如果我对您的理解正确,那么您希望一个对