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

问题描述 投票:1回答:1

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 "";
    }
    }
    }
java linux shell prompt processbuilder
1个回答
0
投票

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

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

  1. 您可以将此代码复制粘贴为类,将其编译为jar并运行它。
  2. 它在WSL Ubuntu 16.04中得到验证。
  3. 通过设置binaryCommand[0]="touch";and 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_; }
© www.soinside.com 2019 - 2024. All rights reserved.