Shell脚本在失败时未记录Java退出状态
我正在尝试编写一个shell脚本来记录Java程序的退出状态。脚本应该简单地启动一个Java应用程序,如果Java应用程序由于某种原因没有运行,shell脚本应该检测到这一点并采取缓解措施 以下是我的脚本: 我已经编写了一个运行良好的简单Swing GUI。但是,我将其打包为一个jar,而没有指定入口点。因此,我应该得到以下错误:Shell脚本在失败时未记录Java退出状态,java,shell,exit-code,Java,Shell,Exit Code,我正在尝试编写一个shell脚本来记录Java程序的退出状态。脚本应该简单地启动一个Java应用程序,如果Java应用程序由于某种原因没有运行,shell脚本应该检测到这一点并采取缓解措施 以下是我的脚本: 我已经编写了一个运行良好的简单Swing GUI。但是,我将其打包为一个jar,而没有指定入口点。因此,我应该得到以下错误: Exception in thread "main" java.lang.NoClassDefFoundError: Demo$1 脚本应该检测到应用程序启动失败
Exception in thread "main" java.lang.NoClassDefFoundError: Demo$1
脚本应该检测到应用程序启动失败
在我尝试使用&在后台启动Java应用程序之前,所有这些都可以正常工作。每当我这样做:
java -jar $APPFOLDER/$APPNAME*.jar > $LOGFOLDER/$APPNAME"_$(date+%Y.%m.%d.%s).log" &
脚本始终为$?,返回一个0,表示它已通过。我做错了什么?有没有更好的方法来检测应用程序是否无法启动
谢谢 等等!您正在记录退出状态的
等待
这就是为什么在脚本中看到意外结果的原因。查看bash的手册页(wait
是bash内置的,因此您需要阅读bash手册):
等等
等待每个指定的子进程并返回其终止状态。每个n可以是一个进程ID。。。如果未给出n,,则等待所有当前活动的子进程,返回状态为0(!)。如果n指定一个不存在的进程或作业,则返回状态为127。否则,返回状态为最后一个进程的退出状态。。。等待
由于您尚未指定n
(要等待的子pid),根据规范,返回状态为零
另一个问题是:你真的需要等待吗
如果不需要在后台运行应用程序,只需执行以下操作:
echo "Starting new app"
java -jar $APPFOLDER/$APPNAME*.jar > $LOGFOLDER/$APPNAME"_$(date+%Y.%m.%d.%s).log"
STATUS=$?
唯一的区别是我删除了不必要的wait
如果出于某种原因,您需要在后台运行应用程序并稍后读取退出状态,那么您需要等待该pid。要找出最后一个后台进程的pid,请使用特殊变量$代码>:
echo "Starting new app"
java -jar $APPFOLDER/$APPNAME*.jar > $LOGFOLDER/$APPNAME"_$(date+%Y.%m.%d.%s).log" &
CHILDPID=$!
wait "${CHILDPID}"
STATUS=$?
下面是它工作原理的简短示例:
user@s:~$ (sleep 10 && exit 42)&
[1] 27792
user@s:~$ wait "$!"
[1]+ Exit 42 ( sleep 10 && exit 42 )
user@s:~$ echo $?
42
我想知道的是,应用程序启动时是否失败。在前者的情况下,我的脚本将打包应用程序,并在以前的版本中扮演角色。
这个目的太模糊了。您是否只对缺少依赖项感兴趣
我认为没有一种简单的方法可以区分JRE非零出口代码和java应用程序非零出口代码
我可以想象展开部署的许多其他原因,其中许多不会导致非零退出代码。您想在后台运行应用程序,但还要等待其状态?这不是违背了后台任务的目的吗?我想知道的是,应用程序启动时是否失败。在前者的情况下,我的脚本将打包应用程序,并在以前的版本中扮演角色。不过,这是今后的事了。我只是想看看应用程序启动是否正常。也许“退出状态”是一个错误的术语。应该在什么时候检查状态?你可以等待进程结束(依我看,这意味着你不需要后台进程),也可以在某个或多或少的随机点进行检查,因为应用程序失败需要一点时间(但尚未定义)。你可以检查进程是否仍然处于活动状态,我认为这大概是系统执事的方法。一个应用程序在退出之前没有“退出代码”,只有在你等待应用程序退出时,你才能看到该退出代码。因此,正如zapl所说,如果你不想等待,那么你可以定期检查你的应用程序,看看它是否仍然有效。(如果你知道你的应用程序需要花费X
很长时间才能正确启动或死亡,那么你可以在该点之后检查一次。但是,更可能的是,你不知道这一点,那么你只需要继续检查,直到它可能死亡或停止关心为止。@Seanimus有什么让你不清楚的吗?
user@s:~$ (sleep 10 && exit 42)&
[1] 27792
user@s:~$ wait "$!"
[1]+ Exit 42 ( sleep 10 && exit 42 )
user@s:~$ echo $?
42