我正在尝试编写一个Shell脚本来记录Java程序的退出状态。该脚本应该简单地启动Java应用程序,并且如果Java应用程序由于某种原因未运行,则Shell脚本应检测到此情况并采取缓解措施。
#!/bin/bash
APPNAME="app"
APPFOLDER=$APPNAME
BACKUP=$APPFOLDER"-backup"
LOGFOLDER=$APPNAME"-log"
echo "Starting new app"
java -jar $APPFOLDER/$APPNAME*.jar > $LOGFOLDER/$APPNAME"_$(date+%Y.%m.%d.%s).log"
wait
STATUS=$?
if [ $STATUS -eq 0 ]
then
echo "Deployment successful" $?
else
echo "Deployment failed: ... derp" $?
fi
我编写了一个运行良好的简单Swing GUI。但是,我将其打包为jar,而未指定入口点。因此,我应该得到错误:
Exception in thread "main" java.lang.NoClassDefFoundError: Demo$1
并且脚本应检测到该应用程序无法启动。
所有这些工作都很好,直到我尝试使用&在后台启动Java应用程序为止。每当我这样做时:
java -jar $APPFOLDER/$APPNAME*.jar > $LOGFOLDER/$APPNAME"_$(date+%Y.%m.%d.%s).log" &
脚本始终为$?返回0,表示已通过。
我究竟做错了什么?有没有更好的方法来检测应用程序是否无法启动?
谢谢!
等待!您正在记录的退出状态wait
!
这就是为什么您在脚本中看到意外结果的原因。查看bash的手册页(bashwait
是内置的,因此您需要阅读bash手册):
等待[-n] [n ...]
等待每个指定的子进程并返回其终止状态。每个n可能是一个进程ID ...如果未给出n ,则等待所有当前活动的子进程,并且返回状态为零(!)。如果n指定不存在的进程或作业,则返回状态为127。否则,返回状态为等待的最后一个进程的退出状态。
由于您尚未指定n
(要等待的子pid),因此返回状态根据规范为零。
另一个问题是:您真的需要一个wait
。
如果您不需要在后台运行您的应用程序,则只需执行以下操作:
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应用程序非零退出代码。
我可以想象有很多其他原因可以展开部署,其中许多原因不会导致退出代码为非零。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句