【问题标题】:Exit(1) when running exec on java在 java 上运行 exec 时退出 (1)
【发布时间】:2023-03-17 08:29:01
【问题描述】:

当我在 linux 中执行我的 java 文件时,我正在 java 程序中运行 sed 命令。 当我在 linux 中单独运行命令时,这将起作用 -> sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt

但是,当我在 linux 中运行我的 java 程序时,它返回 exit(1) 错误。我已通读并用作数组,但仍然失败。

public static void main(String[] args) {
    String[] cmd = {"sed", "sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt"};
    String s;
    Process p;
    try {
        p = Runtime.getRuntime().exec(cmd);
        BufferedReader br = new BufferedReader(
                new InputStreamReader(p.getInputStream()));
        while ((s = br.readLine()) != null) {
            System.out.println("line: " + s);
        }
        p.waitFor();
        System.out.println("exit: " + p.exitValue());
        p.destroy();
    } catch (Exception e) {
    }
}

【问题讨论】:

  • 我怀疑您是否可以将> 作为参数传递并将其解析为“输出重定向”。请参阅here 以获得更好的方法。
  • '>' 是 shell 语法,我不认为你是通过 'exec' 运行 shell。
  • 你根本不需要sed。 Java 可以做所有sed 可以做的事情。使用 Java 意味着它可以在没有安装 sed 的系统上运行(比如 Windows)。
  • @Joe ,这可以从 .sh 文件启动执行。但我试图在 java 本身内执行而不需要创建额外的 .sh 脚本

标签: java unix


【解决方案1】:

你不需要sed。 Java 可以做所有sed 可以做的事情。

在您的情况下,您似乎正在使用 sed 从文件中删除第一行和最后一行。下面是你在 Java 中的做法:

Path source = Path.of("/home/sample/testdata.txt");
Path destination = Path.of("/home/output/testupdate.txt");

long lineCount;
try (Stream<?> lines = Files.lines(source)) {
    lineCount = lines.count();
}

long lastLine = lineCount - 1;

try (BufferedReader in = Files.newBufferedReader(source);
     BufferedReader out = Files.newBufferedWriter(destination)) {

    // Skip first line
    String line = in.readLine();

    long counter = 0;
    while ((line = in.readLine()) != null) {
        if (++counter < lastLine) {
            out.write(line);
            out.newLine();
        }
    }
}

如果出于某种原因您绝对需要使用外部流程,还有许多其他问题和答案可以弥补您的错误:sed 不理解&gt;。通常,解释文件重定向的是shell(如bash)。

运行命令的正确方法是:

ProcessBuilder builder =
    new ProcessBuilder("sed", "1d;$d", "/home/sample/testdata.txt");

builder.redirectOutput(new File("/home/output/testupdate.txt"));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);

Process p = builder.start();

【讨论】:

    【解决方案2】:

    Java 不是 shell,因此不处理重定向 - 您的原始命令只能通过您的 Linux shell 工作,该 shell 可以理解“>”。

    你可以让 Java 启动 shell 来执行命令,比如你使用 bash:

     String[] cmd = {"/bin/bash", "-c"
        , "sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt"};
    

    或者查看其他有用的 cmets,这些 cmets 链接到其他页面以处理 Java 代码中的重定向,或者在 Java 本身内部进行处理(例如使用 Files.lines / 流)。

    【讨论】:

    • 这项工作很好,但我想知道“-c”是什么意思,尝试谷歌搜索但我找不到它的用途
    • “-c”告诉 bash 运行给定的命令,然后退出。如果没有“-c”,bash 将假定参数是一个脚本。比较 bash lsbash -c ls
    猜你喜欢
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多