linux版:MINT 14 netbeans 7.2
我最近很喜欢编程,我遇到了这个困难。 我有一个带有2个jtextarea的GUI,一个我们输入命令的地方,一个命令输出的地方(第三个将实现错误(linux,而不是java) 这对我的原型来说还可以,到目前为止:
命令的输出进入文本区域,但它缺少提示,我尝试了很多东西,但无法绕过它, 我也浏览了很多常见问题,但提示在很多方面使用,但不在shell提示符中。 欢迎帮助。
我已经为流程构建器类插入了代码(现在请忽略大写字母等最佳实践,它只是一个原型,如果原型工作,我会有编程器)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
/**
*
* @author bane
*/
public class myprocessBuilderRunCommand {
public static String myprocessBuilderRunCommand(String command, boolean waitForResponse) {
String response = "";
ProcessBuilder pb = new ProcessBuilder("bash", "-c", command);
pb.redirectErrorStream(true);
System.out.println("Linux command: " + command);
try {
Process shell = pb.start();
if (waitForResponse) {
// To capture output from the shell
InputStream shellIn;
shellIn = shell.getInputStream();
// Wait for the shell to finish and get the return code
int shellExitStatus = shell.waitFor();
System.out.println("Exit status" + shellExitStatus);
response = convertStreamToStr(shellIn);
shellIn.close();
}
}
catch ( IOException | InterruptedException e) {
System.out.println("Error occured while executing Linux command. Error Description: "
+ e.getMessage());
}
return response;
}
/*
* To convert the InputStream to String we use the Reader.read(char[]
* buffer) method. We iterate until the Reader return -1 which means
* there's no more data to read. We use the StringWriter class to
* produce the string.
*/
public static String convertStreamToStr(InputStream is) throws IOException {
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader;
reader = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
}
else {
return "";
}
}
}
答案 0 :(得分:0)
据我了解,您正在寻找一种从Java代码执行命令并在不同窗口中显示输出的方法。这是一个有效的示例,该命令执行命令echo 1
,然后为输出true
返回1
,为输出false
返回0
,(在所有其他情况下均引发异常) 。这样,您可以将输出重定向到所需的任何位置。
我还添加了设置工作路径和环境变量的步骤,这对于您的特定示例不是必需的,因此您可以将其删除。
通过设置binaryCommand[0]="touch";
和binaryCommand[1]="1";
,重新编译并运行.jar
文件来验证设置工作目录的作用。
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Map;
import java.util.StringJoiner;
public class GenerateOutput {
/**
* This code can execute a command and return the binary value of it's output if it
* is actually binary.
*
* compile this project into a .jar and run it with for example:
* java -jar readOutputOfCommand.jar
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
boolean answerYes = false; // no yes answer to any command prompts is needed.
// to execute a command with spaces in it in terminal, put them in an array of Strings.
String[] binaryCommand = new String[2];
// write a command that gives a binary output:
binaryCommand[0] = "echo";
binaryCommand[1] = "1";
// pass the commands to a method that executes them
System.out.println("The output of the echo command = "+executeCommands(binaryCommand,answerYes));
}
/**
* This executes the commands in terminal.
* Additionally it sets an environment variable (not necessary for your particular solution)
* Additionally it sets a working path (not necessary for your particular solution)
* @param commandData
* @param ansYes
* @throws Exception
*/
public static boolean executeCommands(String[] commands,Boolean ansYes) throws Exception {
String capturedCommandOutput = null;
System.out.println("Incoming commandData = "+Arrays.deepToString(commands));
File workingDirectory = new File("/mnt/c/testfolder b/");
// create a ProcessBuilder to execute the commands in
ProcessBuilder processBuilder = new ProcessBuilder(commands);
// this is not necessary but can be used to set an environment variable for the command
processBuilder = setEnvironmentVariable(processBuilder);
// this is not necessary but can be used to set the working directory for the command
processBuilder.directory(workingDirectory);
// execute the actual commands
try {
Process shell = processBuilder.start();
// capture the output stream of the command
BufferedReader reader = new BufferedReader(new InputStreamReader(shell.getInputStream()));
StringJoiner sj = new StringJoiner(System.getProperty("line.separator"));
reader.lines().iterator().forEachRemaining(sj::add);
capturedCommandOutput = sj.toString();
System.out.println("The output of this command ="+ capturedCommandOutput);
// here you connect the output of your command to any new input, e.g. if you get prompted for `yes`
new Thread(new SyncPipe(shell.getErrorStream(), System.err)).start();
new Thread(new SyncPipe(shell.getInputStream(), System.out)).start();
PrintWriter stdin = new PrintWriter(shell.getOutputStream());
//This is not necessary but can be used to answer yes to being prompted
if (ansYes) {
System.out.println("WITH YES!");
stdin.println("yes");
}
// write any other commands you want here
stdin.close();
// this lets you know whether the command execution led to an error(!=0), or not (=0).
int returnCode = shell.waitFor();
System.out.println("Return code = " + returnCode);
} catch (IOException e1) {
e1.printStackTrace();
}
return retrieveBooleanOutput(capturedCommandOutput);
}
private static boolean retrieveBooleanOutput(String commandOutput) throws Exception {
if (commandOutput != null && commandOutput.length() == 1) {
if (commandOutput.contains("0")) {
return false;
} else if (commandOutput.contains("1")) {
return true;
}
}
throw new Exception("The output is not binary.");
}
/**
* source: https://stackoverflow.com/questions/7369664/using-export-in-java
* @param processBuilder
* @param varName
* @param varContent
* @return
*/
private static ProcessBuilder setEnvironmentVariable(ProcessBuilder processBuilder){
String varName = "variableName";
String varContent = "/mnt/c/testfolder a/";
Map<String, String> env = processBuilder.environment();
System.out.println("Setting environment variable "+varName+"="+varContent);
env.put(varName, varContent);
processBuilder.environment().put(varName, varContent);
return processBuilder;
}
}
class SyncPipe implements Runnable
{
/**
* This class pipes the output of your command to any new input you generated
* with stdin. For example, suppose you run cp /mnt/c/a.txt /mnt/b/
* but for some reason you are prompted: "do you really want to copy there yes/no?
* then you can answer yes since your input is piped to the output of your
* original command. (At least that is my practical interpretation might be wrong.)
* @param istrm
* @param ostrm
*/
public SyncPipe(InputStream istrm, OutputStream ostrm) {
istrm_ = istrm;
ostrm_ = ostrm;
}
public void run() {
try
{
final byte[] buffer = new byte[1024];
for (int length = 0; (length = istrm_.read(buffer)) != -1; )
{
ostrm_.write(buffer, 0, length);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private final OutputStream ostrm_;
private final InputStream istrm_;
}