杰瑞科技汇

shell 调用java 返回值

  1. Shell 如何获取 Java 程序的退出状态码 (Exit Status):这是最常用、最标准的 Unix/Linux 约定,用于表示程序是成功执行还是遇到了错误。
  2. Java 程序如何向 Shell 输出数据(标准输出/标准错误):这通常用于将计算结果、日志等信息传递回 Shell。

下面我将详细解释这两个方面,并提供完整的示例。

shell 调用java 返回值-图1
(图片来源网络,侵删)

获取 Java 程序的退出状态码

在 Shell 中,任何一个命令执行后都会返回一个状态码,约定俗成的是:

  • 0 表示成功执行。
  • 非零 表示执行失败,不同的非零值可以代表不同的错误类型。

Java 程序的退出状态码由 System.exit(int status) 方法决定,如果不调用该方法,Java 程序正常执行完毕后,默认返回 0

关键 Shell 变量:

在 Shell 中, 是一个特殊变量,它保存了上一个前台执行的命令的退出状态码。

示例步骤

步骤 1:创建一个简单的 Java 程序

shell 调用java 返回值-图2
(图片来源网络,侵删)

这个程序会根据传入的参数决定是成功退出还是失败退出。

ExitStatusDemo.java:

public class ExitStatusDemo {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("用法: java ExitStatusDemo <success|fail>");
            System.exit(1); // 参数错误,返回 1
        }
        String command = args[0];
        if ("success".equalsIgnoreCase(command)) {
            System.out.println("Java 程序执行成功,准备退出。");
            System.exit(0); // 成功,返回 0
        } else if ("fail".equalsIgnoreCase(command)) {
            System.err.println("Java 程序执行失败,准备退出。");
            System.exit(2); // 失败,返回 2
        } else {
            System.out.println("未知命令: " + command);
            System.exit(3); // 未知错误,返回 3
        }
    }
}

步骤 2:编译 Java 程序

javac ExitStatusDemo.java

步骤 3:在 Shell 脚本中调用并检查返回值

创建一个 Shell 脚本,test_exit_status.sh

test_exit_status.sh:

#!/bin/bash
echo "测试 1: 调用 Java 程序并传入 'success'"
java ExitStatusDemo success
# $? 保存了上一个命令的退出码
JAVA_EXIT_CODE=$?
echo "Java 程序的退出码是: $JAVA_EXIT_CODE"
if [ $JAVA_EXIT_CODE -eq 0 ]; then
    echo "测试 1 结果: 成功"
else
    echo "测试 1 结果: 失败"
fi
echo -e "\n----------------------------------------\n"
echo "测试 2: 调用 Java 程序并传入 'fail'"
java ExitStatusDemo fail
JAVA_EXIT_CODE=$?
echo "Java 程序的退出码是: $JAVA_EXIT_CODE"
if [ $JAVA_EXIT_CODE -eq 0 ]; then
    echo "测试 2 结果: 成功"
else
    echo "测试 2 结果: 失败"
fi

步骤 4:运行 Shell 脚本

首先给脚本添加执行权限,然后运行它:

chmod +x test_exit_status.sh
./test_exit_status.sh

预期输出:

测试 1: 调用 Java 程序并传入 'success'
Java 程序执行成功,准备退出。
Java 程序的退出码是: 0
测试 1 结果: 成功
----------------------------------------
测试 2: 调用 Java 程序并传入 'fail'
Java 程序执行失败,准备退出。
Java 程序的退出码是: 2
测试 2 结果: 失败

从输出中可以清楚地看到,Shell 成功捕获了 Java 程序通过 System.exit() 设置的返回值。


获取 Java 程序的标准输出

除了状态码,Java 程序通过 System.out.println() 输出的内容会进入标准输出流,而通过 System.err.println() 输出的内容会进入标准错误流,Shell 可以轻松捕获这些流。

关键 Shell 操作符

  • 或反引号 `` ... `:命令替换,它会捕获一个命令的标准输出,并将其作为字符串赋值给一个变量。
  • >:将标准输出重定向到文件。
  • 2>:将标准错误重定向到文件。
  • &>:将标准输出和标准错误都重定向到文件。
  • command 2>&1:将标准错误合并到标准输出。

示例步骤

步骤 1:创建一个输出数据的 Java 程序

OutputDemo.java:

public class OutputDemo {
    public static void main(String[] args) {
        // 正常输出,会进入标准输出
        System.out.println("这是标准输出的第一条消息。");
        // 错误信息,会进入标准错误
        System.err.println("这是标准错误的消息。");
        // 如果有参数,打印出来
        if (args.length > 0) {
            System.out.println("你传入的参数是: " + args[0]);
        }
    }
}

步骤 2:编译

javac OutputDemo.java

步骤 3:在 Shell 中捕获输出

场景 A:只捕获标准输出

#!/bin/bash
echo "--- 只捕获标准输出 ---"
# $(...) 会捕获 System.out.println 的内容
output=$(java OutputDemo hello)
echo "从 Java 程序捕获到的标准输出内容是:"
echo "'$output'"
echo "Java 程序的退出码是: $?"

运行结果:

--- 只捕获标准输出 ---
这是标准错误的消息。  <-- 这行没有在 $output 变量中
从 Java 程序捕获到的标准输出内容是:
'这是标准输出的第一条消息。
你传入的参数是: hello'
Java 程序的退出码是: 0

场景 B:将标准输出和标准错误都重定向到文件

#!/bin/bash
echo "--- 将所有输出重定向到文件 output.log ---"
java OutputDemo test > output.log 2>&1
# 或者直接用 java OutputDemo test &> output.log
echo "Java 程序的退出码是: $?"
echo "请查看 output.log 文件的内容。"

output.log 文件的内容将是:

这是标准输出的第一条消息。
这是标准错误的消息。
你传入的参数是: test

最佳实践:结合状态码和标准输出

在实际应用中,一个健壮的 Shell 脚本通常会同时检查 Java 程序的退出状态码和。

  • 用退出状态码判断“成功与否”:这是一个可靠、快速的信号。
  • 用标准输出传递“数据”:这是传递计算结果、日志等详细信息的方式。

示例:一个完整的健壮调用

假设我们有一个 Java 工具,它执行一个计算,成功时返回结果,失败时返回错误信息。

Calculator.java:

public class Calculator {
    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println("错误: 必须提供两个参数。");
            System.exit(1);
        }
        try {
            int a = Integer.parseInt(args[0]);
            int b = Integer.parseInt(args[1]);
            int sum = a + b;
            System.out.println(sum); // 将计算结果输出到标准输出
            System.exit(0);
        } catch (NumberFormatException e) {
            System.err.println("错误: 参数必须是整数。");
            System.exit(2);
        }
    }
}

robust_call.sh:

#!/bin/bash
echo "执行计算: 10 + 20"
# 调用 Java 程序,并立即捕获其输出和退出码
# 使用 'if' 语句可以方便地检查退出码
if java Calculator 10 20; then
    # 如果退出码为 0,则执行这里的代码
    # $(...) 中的命令已经执行成功,所以可以直接捕获输出
    result=$(java Calculator 10 20)
    echo "计算成功!"
    echo "结果是: $result"
else
    # 如果退出码非 0,则执行这里的代码
    echo "计算失败!" >&2 # 将错误信息输出到标准错误
    exit 1 # 让当前脚本也以失败状态退出
fi
echo -e "\n执行计算: 10 abc"
if java Calculator 10 abc; then
    result=$(java Calculator 10 abc)
    echo "计算成功!"
    echo "结果是: $result"
else
    echo "计算失败!" >&2
    exit 1
fi

运行 robust_call.sh 的输出:

执行计算: 10 + 20
30
计算成功!
结果是: 30
执行计算: 10 abc
错误: 参数必须是整数。
计算失败!

这个脚本清晰地展示了如何根据 Java 程序的成败执行不同的逻辑,并在成功时处理其返回的数据。

目的 Java 端 Shell 端
返回执行状态 System.exit(0); (成功)
System.exit(1); (失败)
java MyProgram
if [ $? -eq 0 ]; then ...
或者 if java MyProgram; then ...
返回数据 System.out.println("data"); output=$(java MyProgram)
echo "Got: $output"
返回错误信息 System.err.println("error msg"); java MyProgram 2> error.log
java MyProgram > all.log 2>&1
最佳实践 System.exit() 表示程序是否成功,用 System.out/System.err 输出业务数据和日志。 先检查 或使用 if 判断成败,再决定是否处理 捕获的输出。
分享:
扫描分享到社交APP
上一篇
下一篇