【问题标题】:How to return some value to shell from Java program?如何从Java程序返回一些值给shell?
【发布时间】:2015-10-19 06:12:32
【问题描述】:

我想从 shell 脚本运行 Java 程序。所以我做了类似下面的操作

我的测试Java文件如下

public class EchoTest {
    public static void main (String args[]) {
    System.out.println ("scuccess ..!!");
}

我的测试shell脚本文件如下

out=$(java EchoTest)    
echo $out

我已经编译了 java 程序,然后我运行了那个 shell 脚本(比如 $sh Myscript.sh)。现在它将输出打印到控制台上。现在它工作正常。

如果我写一个像下面这样的程序(抛出一些异常)

  public class EchoTest {
        public static void main (String args[]) {
        System.out.println ("Value is "+(2/0));
    }

它只是将 java 异常打印到控制台上。但我的要求是我希望它在控制台上打印 0 或 1,即我想在我的 java 程序失败时获得 0(零),并希望在 java 程序成功执行时获得 1(一)。

【问题讨论】:

  • 错误不会去正常输出,你试过echo $err吗?
  • 嗨@FredericHenri,感谢您的及时回复,实际上我不想将Java程序的任何异常打印到控制台上只想在成功时返回零,在失败时返回1。请帮我这样做
  • 如果您希望返回 unix 风格的返回值,请查看 System.exit(int)。
  • 不像@chsh,只是我想在java程序失败时打印零或一些我自己的失败消息
  • 2/0 总是会抛出 ArithemeticException 因为数学不允许你除以零。

标签: java linux shell


【解决方案1】:

java 程序的文档说:

退出状态

启动器通常会返回以下退出值,通常是在使用错误参数、严重错误或从 Java 虚拟机引发的异常调用启动器时。但是,Java 应用程序可以选择使用 API 调用 System.exit(exitValue) 返回任何值。

  • 0:成功完成。
  • >0:发生错误。

因此,如果您不执行任何操作,JVM 会遵循通常的约定,即在成功完成时向调用者返回 0 值,并在出错时返回非空值。

你的 shell 脚本应该是:

java EchoTest
if [ $? -eq 0]
then echo 1
else echo 0
fi

这意味着您可以忽略标准输出和标准错误,而只依赖 JVM 的退出状态。

根据@alk 的建议,您甚至可以将第一行替换为out = $( java EchoTest ) 并在success 分支中使用$out(当$?0 时)

【讨论】:

  • 这也可以通过执行out=$(java EchoTest) 并仅在“成功”分支中打印出out 来与OP 1st 方法结合使用,如果$? 等于0,则会说。
  • @prasad:通过将stdout 重定向到类似out=$(java EchoTest 2>error.log)cat error.log 在“失败”分支中的错误文件,或者如果您是对错误消息不感兴趣只需将error.log 替换为/dev/null
  • 嗨@alk,你的意思是这样 out=$(java EchoTest 2>error.log) if [ $? -eq 0 ] 然后 echo "1" else cat error.log fi
  • @prasad :通过文件传递时会有细微差别:您应该避免同时启动 2 个或更多 shell。但是,如果您只开始一个,它肯定是一个不错且简单的解决方案。不使用文件的替代方法需要专用程序。
  • @SergeBallesta 你能提供脚本吗?
【解决方案2】:

您需要将System.exit(code) 与您想要的代码一起使用,具体取决于您是否检测到错误/异常

你将拥有

System.exit(0) // if you detect error, you need to handle exception
System.exit(1) // when no error

【讨论】:

  • 这里我还要注意,大多数程序在程序成功运行时返回 0,大于 0 的数字表示特定错误。
  • 明确,但他特别提到当我的java程序失败时0(零),并希望在java程序成功执行时得到1(一)。
【解决方案3】:

一个更完整的从 shell 处理程序的例子可能是

#!/bin/bash
#
# run.sh command
#
# Runs command and logs the outcome to log.<pid> and err.<pid>.
#

cmd=${1}

# Run cmd and log standard output (1) to log.<pid> and standard error (2) to err.<pid>.
$cmd 1>log.$$ 2>err.$$

# Copy the return code from cmd into result.
result=$?

# Test whether result is 0.
if [ $result -eq 0 ]; then
   echo "$cmd" succeeded.
   cat log.$$
else
   echo "$cmd" failed with result = $result!
   cat err.$$
fi

exit $result


# eof

$$ 评估 shell 的 pid,因此代码可以与自身的副本并行运行。

像这样调用上面的脚本

$ run.sh "java myprogram"

【讨论】:

  • 嗨@alk,最后我得到了这个脚本的预期输出,
  • Hi@alk,你能解释一下这行语句吗,cmd="java EchoTest" $cmd >log.$$ 2>err.$$ result=$?
  • @prasad:要了解这一行发生了什么,您想阅读 Standard Streams。例如,您可以在此处执行此操作:en.wikipedia.org/wiki/Standard_streams
【解决方案4】:

非常感谢大家的回复。 我得到了以下脚本的解决方案,但我不知道这里发生了什么, 请解释一下这里发生了什么。

cmd="java EchoTest"

$cmd >log.$$ 2>err.$$

result=$?

if [ $result -eq 0 ]; then

   echo "1"

else

    echo "0"

   #echo $result

fi

rm log.$$ >/dev/null

rm err.$$ >/dev/null

【讨论】:

  • @prasad :这不是一个真正的答案,但我知道您不能将代码放在评论中:-)。如果 alk 添加到其答案中的 cmets 足够了,则应将其删除(并接受 alk 的答案...)
  • 是的@SergeBallesta,这个解决方案仅基于alk的评论,我只是稍微修改了一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 2013-03-01
  • 2015-11-12
  • 2015-04-13
相关资源
最近更新 更多