【问题标题】:Passing to Linux's "here string" via Java通过 Java 传递给 Linux\'s \"here string\"
【发布时间】:2022-10-13 04:07:19
【问题描述】:

我正在尝试使用<<< 将字符串传递给 Linux 命令:

cat <<< 'Hello'

虽然这在终端中完美运行,但 Java 不会执行此操作

String cmd = "cat <<< 'Hello'";
Process p = new ProcessBuilder(cmd.split(" ")).start();
String stderr = IOUtils.toString(p.getErrorStream(), Charset.defaultCharset());
String stdout = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());
System.out.println(stderr);

来自终端的错误:

cat: '<<<': No such file or directory
cat: "'hello'": No such file or directory

为什么呢?没有&lt;&lt;&lt; 的命令以通常的方式执行。

【问题讨论】:

  • 因为输入和输出重定向是特征。
  • 好的了解了。谢谢。有什么解决方法吗?
  • 通过调用 'bash' (String cmd='bash') 或任何你喜欢的方式打开 shell,然后使用 stdio (p.getOutputstream) 将命令写入 shell,并使用 p.getInputstream 读取结果
  • 我的意思是String input = "Hello";。然后您可以将p.getOutputStream() 的值包装在OutputStreamWriter 中,并将input 写入该OutputStreamWriter。
  • 请注意,&lt;&lt;&lt; 通过创建一个临时文件、将字符串写入其中并将该文件连接到标准输入来工作。当然,您可以在 Java 中自己完成所有这些工作,而完全不依赖 shell 功能。

标签: java bash


【解决方案1】:

正如其他人指出的那样,&lt;&lt;&lt; 是 shell 的一种功能,例如 bash。你可以从您的 ProcessBuilder 调用 bash……但实际上,您不需要 here-string。你有Java。

以下是将已知输入传递给命令的方法:

String input = "Hello";

ProcessBuilder builder = new ProcessBuilder("cat");
builder.inheritIO();
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
Process p = builder.start();

try (Writer processInput =
    new OutputStreamWriter(p.getOutputStream(), Charset.defaultCharset())) {

    processInput.write(input);
}

ProcessBuilder的inheritIO方法会导致子进程的标准输出出现在Java程序的标准输出中,同样,子进程的标准错误也会出现在Java程序的标准错误中。

如果要捕获进程的标准输出,可以将inheritIO() 替换为对redirectError 的显式调用:

String input = "Hello";

ProcessBuilder builder = new ProcessBuilder("cat");
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
Process p = builder.start();

try (Writer processInput =
    new OutputStreamWriter(p.getOutputStream(), Charset.defaultCharset())) {

    processInput.write(input);
}

try (BufferedReader processOutput = new BufferedReader(
    new InputStreamReader(p.getInputStream(), Charset.defaultCharset()))) {

    String line;
    while ((line = processOutput.readLine()) != null) {
        // ...
    }
}

【讨论】:

    【解决方案2】:

    试试这个方法:

    processBuilder.command("bash", "-c", cmd);

    通常,输出重定向是 shell 功能,ProcessBuilder 无法以您提供的方式理解命令。

    【讨论】:

      猜你喜欢
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-16
      • 2020-03-10
      • 1970-01-01
      • 2023-03-15
      相关资源
      最近更新 更多