gpt4 book ai didi

java - processbuilder - linux - 提示未在输出流中捕获

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:36:53 26 4
gpt4 key购买 nike

Linux 版本:MINT 14网 bean 7.2

我刚接触编程,遇到了这个困难。我有一个带有 2 个 jtextarea 的 GUI,一个是我们键入命令的地方,一个是命令输出的地方(第三个将实现错误(linux,不是 java)这对我的原型(prototype)来说没问题,到目前为止:

命令的输出进入文本区域,但缺少提示,我尝试了很多东西,但无法绕过它,也浏览了很多faq,但是prompt用了那么多,shell prompt中却没有。欢迎帮助。

我已经插入了流程构建器类的代码(请暂时忽略大写字母等最佳实践,它只是一个原型(prototype),如果原型(prototype)有效,我会安排编码人员)

    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 "";
}
}
}

最佳答案

据我了解,您正在寻找一种从 Java 代码执行命令并在不同窗口中显示输出的方法。这是一个执行命令 echo 1 然后返回 true 用于输出 1false 用于输出 0,(在所有其他情况下抛出异常)。这样你就可以将输出重定向到任何你想要的地方。

我还添加了设置工作路径和环境变量,这对于您的特定示例来说不是必需的,因此您可以将其删除。

  1. 您可以将此代码复制粘贴为一个类,将其编译为 jar 并运行。
  2. 已在 WSL Ubuntu 16.04 中验证。
  3. 设置工作目录通过设置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_;
    }

关于java - processbuilder - linux - 提示未在输出流中捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16310105/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com